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

Shell 批量重命名子目录中的文件扩展名,shell,unix,automation,busybox,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上运行时,必须转义将

我正在尝试在linux中创建一个批处理文件,它允许我更改多个子目录中文件的扩展名。经过多次搜索和试验,我找到了一个解决方案:

find /volume1/uploads -name "*.mkv" -exec rename .mkv .avi {} +
在运行脚本时,我遇到以下错误:

find: -exec CMD must end by ';'
我试着加上;和\;(有或没有+),但没有用。命令有什么问题,我如何修复它


编辑:在使用DSM 4.2的Synology NAS上运行时,必须转义将由
bash解释的所有字符。在您的例子中,这些是分号和大括号(您忘记在代码中转义后者):

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

find /volume1/uploads -name "*.mkv" -exec rename 's/\.mkv$/.avi/' \{\} \;
find /volume1/uploads -name "*.mkv" | while read filename; 
do mv -v "${filename}" "$(echo "${filename}" | sed -e 's/\.mkv$/\.avi/')"
done
更新 如果不想(或不能)使用perl的
rename
脚本,可以使用以下简单的bash脚本并将其保存为/tmp/rename.sh

#!/bin/sh
INFILE=$1
OUTFILE="${INFILE%.mkv}.avi"
echo "moving ${INFILE} to ${OUTFILE}"
mv "${INFILE}" "${OUTFILE}"
使其可执行(
chmodu+x/tmp/rename.sh
)并调用:

find /volume1/uploads -name "*.mkv" -exec /tmp/rename.sh \{\} \;
更新2 事实证明,这个问题实际上不是关于
bash
,而是关于
busybox

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

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

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

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

运行find/volume1/uploads-name“*.mkv”可以得到我感兴趣的所有文件,但是当转义大括号和分号时,我得到了以下错误(对于找到的每个文件):find:rename:没有这样的文件或目录好吧,是您的示例代码使用了
rename
,我假设您知道如何使用它
-exec
标志将只获取一个二进制文件并运行它,因此您显然必须确保您的系统上有一个
重命名
二进制文件它附带了
perl
。无论如何,我会更新答案,使用一个适合您需要的小示例脚本,因为您可能已经猜到我是一个完整的n00b,当它涉及到shell脚本时。我感谢您的帮助!我遵循了您的更新(创建第二个文件chmod并从第一个文件运行),但我遇到另一个错误:“没有这样的文件或目录”对于每个找到的文件。您是否提供了重命名脚本的完整路径以
find
?如果没有,您可能应该这样做;如果您提供了,我已经对脚本进行了一点更新,以便它打印出来告诉您它将要做什么。也许您可以从打印出来的结果中猜出哪里出错了。它一直提供文件未找到错误,因此我尝试了runni将重命名函数(文件2)直接放在-exec之后的命令中。这会产生一个新错误:“nota directory”(它在文件名后面附加了一个/)