如何在 find -exec 语句中使用 >>?

How to use >> inside find -exec statement?

有时我不得不在一堆文件的末尾附加一些文本。我通常会用 find.

找到这些文件

我试过了

find . -type f -name "test" -exec tail -n 2 /source.txt >> {} \;

然而,这会导致将 /source.txt 的最后两行写入名为 {} 的文件,但是多次找到符合搜索条件的文件。

我想我必须以某种方式逃脱 >> 但到目前为止我没有成功。

如有任何帮助,我们将不胜感激。

-exec 只接受一个命令(带可选参数),您不能在其中使用任何 bash 运算符。

所以你需要将它包装在一个 bash -c '...' 块中,它在新的 bash shell.

中执行 '...' 之间的所有内容
find . -type f -name "test" -exec bash -c 'tail -n 2 /source.txt >> ""' bash {} \;

注意:'...' 之后的所有内容都作为常规参数传递,除了它们从 $0 而不是 $1 开始。因此 ' 之后的 bash 用作占位符,以匹配您期望的参数和错误处理在常规 shell 中的工作方式,即 $1 是第一个参数,错误通常以bash 或有意义的东西

如果执行时间是个问题,请考虑做类似 export variable="$(tail -n 2 /source.txt)" 的事情并在 -exec 中使用 "$variable"。这也将始终写入相同的内容,这与在 -exec 中使用 tail 不同,如果文件更改,后者可能会更改。或者,您可以使用 -exec ... + 之类的东西并将其与 tee 配对以一次写入多个文件。

更有效的替代方案(假设 bash 4):

shopt -s globstar
to_augment=( **/test )
tail -n 2 /source.txt | tee -a "${to_augment[@]}" > /dev/null

首先,您创建一个包含所有文件名的数组,使用一个应该等同于您对 find 的调用的简单模式。然后,使用 tee 一次将所需的行附加到所有这些文件。

如果你对find命令有更多的条件,你仍然可以使用它;这个版本不是万无一失的,因为它假定没有文件名包含换行符,但最好留给另一个问题来解决这个问题。

while read -r fname; do
    to_augment+=( "$fname" )
done < <(find ...)