假设一个文件夹中有许多扩展名错误的文件,例如
Song1.avi.mp3
Song2.avi.mp3
Song32.web.mp3
Song23.mp4.mp3
Song2a.mp9.mp3
我只想删除第二个字段 ( web
, avi
, mp4
)。我知道如何使用 sed 但我必须添加扩展名
mv -v $i "$(echo $i|sed 's:.flv::g;s:.avi::g;s:.mp4::g')"
有人知道使用 sed 或 awk 或 perl 的直接方法来仅删除第二个坏扩展吗?
答案1
您不需要任何外部实用程序,您可以使用shell 自己的字符串操作功能。这样可以更轻松地避免使用特殊字符破坏文件名。并记住始终在变量替换周围使用双引号。
mv -v -- "$i" "${i%.*.*}.${i##*.}"
(显然,此代码片段假设文件名确实包含两个扩展名。如果不包含,${i%.*.*}
则为整个文件名。)
答案2
使用 bash 正则表达式:
f=foo.bar.baz.qux
if [[ $f =~ (.+)\.[^.]+\.([^.]+)$ ]];then
new="${BASH_REMATCH[1]}.${BASH_REMATCH[2]}"
if [[ -f "$new" ]]; then
echo "moving $f would overwrite $new"
else
echo mv "$f" "$new"
fi
fi
mv foo.bar.baz.qux foo.bar.qux
这样做的优点是,如果名称中的点少于 2 个,则不执行任何操作。
答案3
如果您需要验证文件名匹配 - 因此只重命名那些实际上具有您尝试修改的两个扩展名的文件 - 您可以这样做:
case ${i##*/} in (*.*.*)
mv -- "$i" "${i%.*.*}.${i##*.}"
;;esac
请理解,如果您不验证匹配并且您"$i"
使用如下的 glob 进行设置:
for i in *
mv "$i" ...
...然后使用mv
与上面相同的命令(以及其他答案)"$i.$i"
如果模式不匹配,可能会导致文件被移动到var 扩展为自身的位置。
答案4
使用命令轻松重mmv
命名:
$ mmv -n '*.*.*' '#1.#3'
或使用rename
命令:
$ rename -n 's:(.*)\..*(\..*):$1$2:' *