【问题标题】:How to use >> inside find -exec statement?如何在 find -exec 语句中使用 >>?
【发布时间】:2015-10-28 02:08:16
【问题描述】:

有时我必须在一堆文件的末尾附加一些文本。我通常会使用find 找到这些文件。

我试过了

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

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

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

任何帮助将不胜感激。

【问题讨论】:

  • -exec bash -c 'tail -n 2 /source.txt >> "$1"' bash {} \;。另外,我还没有对其进行测试,但是将tail -n 2 的输出存储在某个环境变量中,如果您担心性能,编写它可能会更快(也可以使用+tee 变体)
  • 我只是通过管道输入 xargs
  • 这不起作用的原因与this 相同,但不确定这是否被视为重复,因此将我的评论切换为答案。

标签: bash shell find


【解决方案1】:

更有效的替代方案(假设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 ...)

【讨论】:

    【解决方案2】:

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

    因此,您需要将其包装在 bash -c '...' 块中,该块在新的 bash shell 中执行 '...' 之间的所有内容。

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

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

    如果执行时间是个问题,请考虑执行export variable="$(tail -n 2 /source.txt)" 之类的操作,并在-exec 中使用"$variable"。这也将总是写同样的东西,不像在-exec 中使用tail,如果文件改变,它可能会改变。或者,您可以使用 -exec ... + 之类的东西并将其与 tee 配对,以一次写入多个文件。

    【讨论】:

    • 有效!感谢您的解决方案和解释。通常文件不会太多,但如果发生变化,我会回到您的 cmets。
    猜你喜欢
    • 1970-01-01
    • 2014-03-16
    • 2018-03-06
    • 2011-11-30
    • 1970-01-01
    • 2011-04-20
    • 2011-05-01
    • 1970-01-01
    相关资源
    最近更新 更多