Answers:
遍历文件名,并使用参数扩展进行转换:
for f in *.*.*.txt; do i="${f%.txt}"; echo mv -i -- "$f" "${i//./_}.txt"; done
的参数扩展图案,${f//./_}
取代所有.
与S _
S IN的文件名($f
)。
上面将进行空运行,以进行实际的重命名,删除echo
:
for f in *.*.*.txt; do i="${f%.txt}"; mv -i -- "$f" "${i//./_}.txt"; done
如果您想处理任何扩展名,不仅要.txt
:
for f in *.*.*.*; do pre="${f%.*}"; suf="${f##*.}"; \
echo mv -i -- "$f" "${pre//./_}.${suf}"; done
检查删除后echo
采取实际措施:
for f in *.*.*.*; do pre="${f%.*}"; suf="${f##*.}"; \
mv -i -- "$f" "${pre//./_}.${suf}"; done
通用,对于任意数量的点,至少一个:
for f in *.*; do pre="${f%.*}"; suf="${f##*.}"; \
mv -i -- "$f" "${pre//./_}.${suf}"; done
for f in *.*; do ...; done
*.*
在示例中将图案弄直,因为现在代码看起来只适用于固定数量的点。
与perl
基础rename
$ rename -n 's/\.[^.]+$(*SKIP)(*F)|\./_/g' head.body.date.txt
rename(head.body.date.txt, head_body_date.txt)
\.[^.]+$(*SKIP)(*F)
跳过此模式,寻找其他匹配项|\./_/g
全部替换.
为_
或者,使用负前瞻
$ rename -n 's/\.(?![^.]+$)/_/g' head.body.date.txt
rename(head.body.date.txt, head_body_date.txt)
一切正常之后,请删除该-n
选项
使用mv
,sed
并rev
在一行:
mv "head.body.date.txt" "$(echo head.body.date.txt | rev | sed 's/\./_/2g' | rev)"
如果您想将其txt
应用于当前rep中的所有文件,由于mv
工作原理,使用glob似乎很棘手,但是您可以单线for
循环:
for file in *.txt; do mv "$file" "$(echo $file | rev | sed 's/\./_/2g' | rev)"; done
稍长一些,但是您可以在循环中匹配多个模式!
$(ls …)
; 随便吧for file in *.txt
。(2)您应该使用更多引号:mv "$file" "$(…)"
。
rename
其他答案中提出的建议确实听起来更简单……
.tar.gz
是扩展?另外,欢迎来到U&L!