删除文件名中倒数第二个扩展名

删除文件名中倒数第二个扩展名

假设一个文件夹中有许多扩展名错误的文件,例如

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:' *

相关内容