我正在尝试根据图像的尺寸重命名目录中的一组图像。为此,我正在逐步建立命令,使用 Imagemagik 的identify
命令。我目前正在使用echo
并计划在输出正确mv
后切换到它。echo
find * -type f -exec echo "$(identify -format '%w-%h' {})" \;
这会输出一堆空行。但是,当我直接运行它而没有回显时,
find * -type f -exec identify -format '%w-%h' {} \;
它按预期输出尺寸。为什么内部命令不能正常执行?
答案1
那是因为echo
不知道{}
其内部是什么来扩展它,只exec
了解{}
,在这种情况下你应该使用 insh -c
模式。
find . -type f -exec sh -c 'echo "$(identify -format '%w-%h' "$1")"' sh '{}' \;
答案2
使用:
find . -type f -exec sh -c 'echo "$(identify -format %w-%h "$1")"' sh {} \;
解释
问题在于 bash 扩展变量的方式
find * -type f -exec echo "$(identify -format '%w-%h' {})" \;
首先 bash 扩展了 side 中的内容$(...)
:
find * -type f -exec echo 'identify: unable to open image `{}': No such file or directory...' \;
此时 find 将对所有带有相当无用参数的命令使用相同的 exec 语句。您想要做的是抑制 find exec 内部的 bash 扩展。您可以通过将内容放在单引号内来阻止 bash 扩展内容
find * -type f -exec echo '$(identify -format %w-%h {})' \;
但在这里我们完全失去了扩展,我们可以通过运行表达式来将其注入回来sh -c
find * -type f -exec sh -c 'echo "$(identify -format %w-%h {})"' \;
{}
在处理文件名中的空格、引号或任何 shell 特殊字符时,将其置于shell 脚本中也可能会导致一些意外错误。为了解决这个问题,你应该将 the{}
作为参数移至 sh :
find * -type f -exec sh -c 'echo "$(identify -format %w-%h "$1")"' sh {} \;
最后,您可以将 替换为*
,.
让其find
自行查找当前目录中的文件(并包括隐藏的文件,并且对于以 开头的文件名不会失败-
)。
此外,您可以添加-x
标志以sh
使其打印出执行的内容,以帮助调试命令 - 这对于许多文件来说可能非常嘈杂。