find exec '{}' 在 > 之后不可用

Buz*_*zut 8 bash find

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 -cfind -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 的这个答案中有更多的讨论。


ctr*_*lor 8

你有一个答案(https://unix.stackexchange.com/a/481687/4778),但这就是原因。

重定向>、管道|$扩展都是在命令执行之前由 shell 完成的。因此,标准输出optimized_{}find启动之前被重定向到, 。