在Bash/OSX终端中为多个文件添加前缀

5

我希望在bash中向多个文件添加一些文本,在这篇文章中找到了处理prepend的方法:prepend to a file one liner shell?

我可以使用find找到需要处理的所有文件:

find ./ -name "somename.txt"

但是我如何使用管道将这两者结合起来?
4个回答

9

你有几个选项。最简单的可能是使用sed:

find ./ -name somename.txt -exec sed -e '1i\
My new text here' {} \;

如果在文本前面添加'2q',并且使用-i标志,则会更快地完成操作。请注意,此操作将在文件中直接进行。
find ./ -name somename.txt -exec sed -i .bak -e '2q;1i\
My new text here' {} \;

要在多行前添加内容,您需要在每行末尾加上反斜杠。

这会在原始文件周围留下一个带有 .bak 扩展名的备份文件。


这个对我来说似乎可以解决问题,其他好的例子会多次插入文本(我认为是每行一个),我只需要添加-type file并将-e更改为-i即可让sed更新文件。 - DEfusion
是的。使用“iText”匹配每一行,因此在每一行之前插入文本。“1i”仅匹配第一行。“0a”将执行相同操作。“2q”并不是必需的,但可以使sed无需查看每一行并说“不,这也不是第一行”。 - Charlie Martin
尝试了这个命令:find . -iname .java -exec sed -e '1i
/
  • 版权所有 (c) 2012 X 公司。保留所有权利。 */ ' {} ;
得到了以下结果:sed: 3: "1i\n/\n 版权所有 (c) ...": 无效的命令码 *
- mvmn
1
搞定了 - 对于我想要插入的多行文本,如果后面还有另一行,则必须在行末加上 \。在之前的评论中,我的插入文本有多行,应该有换行符。看起来它们被删除了,抱歉。 - mvmn
1
但是仍然存在一个问题 - 文件没有更新,我只在stdout中得到了输出。在Mac OS X 10.6上尝试过这个方法。 - mvmn
解决了。我必须添加-i ""。我知道它在你的第二个命令中,但不在第一个命令中。 - mvmn

1
find . -name "somefiles-*-.txt" -type f | while read line; do  sed -i 'iThis text gets prepended' -- "$line"; done

或者

find . -name "somefiles-*-.txt" -type f | xargs sed -i 'iGets prepended' --

我认为最好的是:

find . -name "somefiles-*-.txt" -type f -exec sed -i 'iText that gets prepended (dont remove the i)' -- '{}' \;

感谢提醒,我已经添加了重要的“-”和“-s”。


通常最好引用 $line ("$line")。不幸的是,带有空格的文件名现在很常见... - mitchnull
这可能是GNU-ism;原始的sed需要'i'后跟换行符,然后是要附加的文本。 - Charlie Martin
对于第二个问题,您需要在find中使用-print0,在xargs中使用-0,以避免处理文件名中带有空格的文件夹时出现问题。对于第三个问题,您应该使用\ +而不是;,以避免为每个文件分叉一个进程。 - Adam Rosenfield
1
对于#3:我尝试过并且它在原始文件的每行之前添加了新文本。 我在i标志后面立即添加了'1'(像这样:-i'i1Text...'),它就可以正常工作了(仅在开头添加一次)。 - Julien-L

-1
find . -name "somename.txt" | while read a; do prepend_stuff_to "$a" ; done

或者

find . -name "somename.txt -exec prepend_stuff_to "{}" \;

-1
find ./ -name "somename.txt" -print0 | xargs -0 -n 1 prepend_stuff_to

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接