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!