我有一批文件,文件名中间包含数字 21 到 29。由于我不想手动删除数百个文件的数量,因此我尝试使用终端:
for f in *;
do for x in {21..29};
rename=`echo "$f" | sed 's/\$x//'`
mv "$f" "$rename"; done;
然而,什么也没有发生。如果我只是为了在包含一些文件的测试文件夹上好玩而将“$x”替换为字母“a”,则第一个字母“a”实际上会被删除,但对于数字来说它不起作用。我究竟做错了什么?
我非常感谢任何帮助!谢谢你!
答案1
您的sed
命令将不起作用,因为$x
在单引号内时不会扩展。然而,你确实使用了错误的工具来完成这项工作。
如果zsh
是可用的 shell,我建议切换到该 shell 并利用其zmv
贡献的模块和内置的数字 glob range <m-n>
:
前任。给定
% ls -d -- *.mp4
'video snap 02 car 23 December.mp4' 'video snap car 23 December.mp4'
然后
% autoload -Uz zmv
% zmv -n '(*) <21-29> (*.mp4)' '$1 $2'
mv -- 'video snap 02 car 23 December.mp4' 'video snap 02 car December.mp4'
mv -- 'video snap car 23 December.mp4' 'video snap car December.mp4'
-n
当您对替换工作正常感到满意时,请删除(无操作)。
如果您不能使用 zsh,那么由于您的数字范围可以用简单的 shell 模式表示,因此您可以在 bash 中执行以下操作:
$ for f in *2[123456789]*.mp4; do echo mv -n -- "$f" "${f/ 2[123456789]}"; done
mv -n -- video snap 02 car 23 December.mp4 video snap 02 car December.mp4
mv -n -- video snap car 23 December.mp4 video snap car December.mp4
在这种情况下,删除 来echo
实际重命名文件(保留-n
,因为这样可以防止名称冲突时被覆盖)。
答案2
for f in *;
do echo "$f" | awk '{gsub("[0-9]{2,}", "", $0); print}' |xargs -I {} mv "$f" {}
done
此代码将循环遍历所有文件,将名称通过管道传递给awk,然后 awk 将替换任何出现的 2 个或更多数字,并将其通过管道传输到MV命令(用于重命名)。
参数用于将标准输入传递到正确的参数位置。
编辑:由于您提供了有关文件名的新信息video snap 02 car 23 December.mp4
,因此此代码应仅删除名称倒数第二个字段中的数字。
for f in *;
do echo "$f" | awk '{gsub("[0-9]", "", $(NF-1)); print}' |sed 's/ / /g' |xargs -I {} mv "$f" {} ;
done