我正在尝试在linux中创建一个批处理文件,这将允许我更改多个子目录中的文件扩展名。经过大量的搜索和实验,我发现了什么似乎是一个解决方案:
find /volume1/uploads -name "*.mkv" -exec rename .mkv .avi {} +
运行脚本时出现以下错误:
find: -exec CMD must end by ';'
我尝试过添加;和\; (有或没有+)但无济于事。命令有什么问题,如何解决?
编辑:使用DSM 4.2在Synology NAS上运行
答案 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 \{\} \;
事实证明,这个问题与bash
无关,而与busybox
有关。
使用像busybox这样有限的shell解释器,最简单的解决方案就是追加新的文件扩展名:
find /volume1/uploads -name "*.mkv" -exec mv \{\} \{\}.avi \;
答案 1 :(得分:0)
不确定DSM 4.2操作系统上的find
和rename
命令有何不同,请尝试以下操作:
find /volume1/uploads -name "*.mkv" | while read filename;
do mv -v "${filename}" "$(echo "${filename}" | sed -e 's/\.mkv$/\.avi/')"
done