Exec 允许我们一次性传递所有参数,{} +或者使用{} \;
现在假设我想重命名所有jpeg,这样做没问题:
find . \( -name '*.jpg' -o -name '*.jpeg' \) -exec mv '{}' '{}'.new \;
Run Code Online (Sandbox Code Playgroud)
但是,如果我需要重定向输出,'{}'则重定向后无法访问。
find . \( -name '*.jpg' -o -name '*.jpeg' \) -exec cjpeg -quality 80 '{}' > optimized_'{}' \;
Run Code Online (Sandbox Code Playgroud)
这行不通。我必须使用 for 循环,在使用之前将 find 的输出存储到变量中。让我们承认,这很麻烦。
for f in `find . \( -name '*.jpg' -o -name '*.jpeg' \)`; do cjpeg -quality 80 $f > optimized_$f; done;
Run Code Online (Sandbox Code Playgroud)
那么有没有更好的办法呢?
oli*_*liv 13
您可以bash -c在find -exec命令中使用,并在 bash 命令中使用位置参数:
find . \( -name '*.jpg' -o -name '*.jpeg' \) -exec bash -c 'cjpeg -quality 80 "$1" > "$(dirname "$1")/optimized_$(basename "$1")"' sh {} \;
Run Code Online (Sandbox Code Playgroud)
{}提供了这种方式$1。
在sh该前{}告诉内壳的“名”,这里使用的字符串中如错误信息时使用。这在关于 stackoverflow 的这个答案中有更多的讨论。
你有一个答案(https://unix.stackexchange.com/a/481687/4778),但这就是原因。
重定向>、管道|和$扩展都是在命令执行之前由 shell 完成的。因此,标准输出optimized_{}在find启动之前被重定向到, 。