我想将许多子文件夹中的大量 wmf 文件(120860!)转换为 svg(27 个子文件夹,每个子文件夹都有许多子子文件夹)。我有这个 bash 脚本可以
for i in `find -iname "*.wmf"`; do
uniconvertor ${i} ${i%.wmf}.svg
done
但它从不转换所有内容,它总是在中间某处停止。有些子文件夹被转换,有些没有,有些只是部分转换。即使我在所有 27 个一级子文件夹中启动 shell 脚本,也只有部分文件被转换。
可能是什么问题呢?
答案1
如果您的文件或文件夹名称中没有换行符,则应使用while
而不是for
循环:
find -iname "*.wmf" | while read file; do
uniconvertor "$file" "${i%.wmf}.svg"
done
这避免了名称中的空格问题以及扩展时参数过多的问题...
答案2
您必须用以下find ...
命令$( )
替换输出:
for i in $( find . -type f -iname '*.wmv` ) ; do ...
但是,在处理第一个文件名之前,您会导致 Bash 生成(并在内部存储)120,860 个文件名的列表。此外(您尚未描述文件名的格式),此技术会错误处理带有空格的文件名,例如A Big File.wmf
。
阅读man find
,尤其是关于--print0
,阅读man xargs
,尤其是关于-0
,阅读man bash
并将您的命令包装在一个在其每个参数上运行的脚本中uniconverter
,并使用类似以下内容:
find . -type f -iname '*.wmv' -print0 | xargs -0 thescript
请务必阅读man bash
并注意文件名中的任何空格。
@steeldriver:谢谢您指出我的错误。阅读man bash
显示:
Enclosing characters in double quotes preserves the literal value of
all characters within the quotes, with the exception of $, `, \, and,
when history expansion is enabled, !. The characters $ and ` retain
their special meaning within double quotes. The backslash retains its
special meaning only when followed by one of the following characters:
$, `, ", \, or <newline>. A double quote may be quoted within double
quotes by preceding it with a backslash.
所以我过度担心 Shell 扩展。