Xargs 将字符串附加到文件

Xargs append string to files

我在一个目录中有多个文本文件。最后我想附加一个字符串。

例如。目录中的文本文件列表。

获取路径的命令:

find -name "*txt"

然后我尝试发送

'echo "example text" > <filename>

所以我尝试了运行以下方法:

find -name "*txt" | xargs echo "example_text" >>

此命令失败。

我只想时不时地在文件中附加一些文本,因为文件的名称不断变化,所以我想使用 xargs

xargs 在这里不太合适。也许循环文件名,如

for file in *.txt; do
    echo "example_text" >>"$file"
done

因为 >> 是一个 shell 指令,如果你想通过 xargs 实现它,你需要让 xargs 启动一个 shell。正如 所示,在许多情况下,shell glob 就足够了,您根本不需要 find;但是如果你确实想要使用find,无论有没有xargs都可以正确使用它。


如果您坚持使用xargs,即使它不是完成这项工作的最佳工具...

find . -name "*.txt" -print0 | xargs -0 sh -c '
  for arg in "$@"; do echo "example_text" >>"$arg"; done
' _

去掉 xargs,只使用 find(使用 -exec ... {} + 以获得相同的性能优势 xargs 否则会提供):

find . -name "*.txt" -exec sh -c '
  for arg in "$@"; do echo "example_text" >>"$arg"; done
' _ {} +

(在上面两个中,_ 替代了 [=21=],所以后面的参数变成了 </code> 和后面的参数,因此在扩展 <code>"$@" 时被迭代).

bash的角度来看,你的命令分为三部分:

  • 竖线字符前(find -name "*txt")
  • 在管道和重定向之间(xargs echo "example_text")
  • 重定向后 ( )

bash 尝试打开重定向后提供的输出文件,但是由于您没有提供任何内容,bash 无法打开“无”并失败。

要解决您的问题,您需要为 xargs 提供一种方法来将您需要的行添加到文件中(无需要求 bash 重定向 xargs 的输出)。一种可行的方法是启动一个执行该操作的子 shell:

find -name "*txt" | xargs -I{} bash -c 'echo "example_text" >> {}'

正如许多人指出的那样,xargs 是不合适的,因此您可以简单地在循环中使用查找和管道到 read 来轻松完成您想要的操作,如下所示。

find . -name "*.txt" | while read fname; do echo "example_text">>$fname; done

将字符串附加到多个文件,使用 tee -a!

Un*x 命令 tee 专为此类操作而构建,而且速度更快!!

find . -type f -name '*.txt' -exec tee -a <<<'Foo bar baz' {} >/dev/null +

但是 herestring 只有在 tee 只执行一次时才会起作用! (感谢 )!

进一步使用 globstar 参见 pure

如果你真的想使用 xargs

find . -type f -name '*.txt' -print0 |
    xargs -0 sh -c 'echo "Foo bar baz"|tee -a "$@" >/dev/null ' _

但是 find 真的需要吗?

如果所有文件都在同一目录下:

tee -a <<<'Foo bar baz' >/dev/null *.txt

否则,在 [ŧag:bash] 下,使用 globstar ( shopt -s globstar ):

tee -a <<<'Foo bar baz' >/dev/null **/*.txt