批量重命名子目录中的文件扩展名

时间:2013-07-01 12:23:01

标签: shell unix automation busybox

我正在尝试在linux中创建一个批处理文件,这将允许我更改多个子目录中的文件扩展名。经过大量的搜索和实验,我发现了什么似乎是一个解决方案:

find /volume1/uploads -name "*.mkv" -exec rename .mkv .avi {} +

运行脚本时出现以下错误:

find: -exec CMD must end by ';'

我尝试过添加;和\; (有或没有+)但无济于事。命令有什么问题,如何解决?

编辑:使用DSM 4.2在Synology NAS上运行

2 个答案:

答案 0 :(得分:0)

你必须转义bash解释的所有字符。在你的情况下,这些是分号和花括号(你忘了在你的代码中逃避后者):

find /volume1/uploads -name "*.mkv" -exec rename .mkv .avi \{\} \;

{}(在我们的情况下为\{\})会扩展为文件名,因此实际调用看起来像rename .mkv .avi /volume1/uploads/foo/bla.mkv(这不是/usr/bin/rename的确切语法需要,至少在我的系统上)。 相反,它会是这样的:

find /volume1/uploads -name "*.mkv" -exec rename 's/\.mkv$/.avi/' \{\} \;

更新

如果您不想(或不能)使用perl的rename脚本,您可以使用以下简单的bash脚本并将其另存为/tmp/rename.sh

#!/bin/sh
INFILE=$1
OUTFILE="${INFILE%.mkv}.avi"
echo "moving ${INFILE} to ${OUTFILE}"
mv "${INFILE}" "${OUTFILE}"

使其可执行(chmod u+x /tmp/rename.sh)并致电:

find /volume1/uploads -name "*.mkv" -exec /tmp/rename.sh \{\} \;

UPDATE2

事实证明,这个问题与bash无关,而与busybox有关。

使用像busybox这样有限的shell解释器,最简单的解决方案就是追加新的文件扩展名:

find /volume1/uploads -name "*.mkv" -exec mv \{\} \{\}.avi \;

答案 1 :(得分:0)

不确定DSM 4.2操作系统上的findrename命令有何不同,请尝试以下操作:

find /volume1/uploads -name "*.mkv" | while read filename; 
do mv -v "${filename}" "$(echo "${filename}" | sed -e 's/\.mkv$/\.avi/')"
done