如何在 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 ...)
有时我不得不在一堆文件的末尾附加一些文本。我通常会用 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 ...)