在每个文件名与 pattern1 匹配的文件中,我想搜索以 pattern2 开头的行,并在这些匹配行上方的新行中添加一些字符串。
举一个简单的例子,假设我在 .txt 文件中递归搜索 potato,并且我想在上面添加 'spam',然后是文件 /tmp/blah.txt
hello
potato
world
not potato
bye
将转变为
hello
spam
potato
world
not potato
bye
对于 shell 向导来说,这听起来像是一项简单的工作,那么实现此目标的最简单方法是什么?我标记了一些我认为可能经常被怀疑的工具,但我愿意听取其他建议。如果它可以在我确认修改文件之前向我显示预览差异,那就更好了。
答案1
我也会在 Perl 中这样做:
$ for f in *txt; do perl -pne 'print "spam\n" if /^potato/' "$f"; done
hello
spam
potato
world
spam
not potato
bye
该-p
标志使 perl 打印输入文件的每一行。-n
意思是“逐行读取输入文件”并将 给出的脚本应用于-e
每一行。然后,脚本本身将打印spam
当前行是否包含,并将打印每一行。结果将是打印在包含 的行上方的potato
字符串。 spam
potato
这将仅打印出新文件而不进行修改。如果您随后想对原始文件进行更改,请使用-i
:
$ for f in *txt; do perl -i.bak -pne 'print "spam\n" if /^potato/' "$f"; done
这将为每个处理过的文件创建一个名为的备份文件foo.txt.bak
,并将更改应用于foo.txt
。
答案2
就我个人而言,我可能会使用 perl 来做这样的事情,但是你可以单独在 bash 中实现你想要的效果:
while read -r line ; do if [[ $line =~ "potato" ]]; then echo spam; fi; echo $line; done < file.txt
如果要将结果放入新文件中:
while read -r line ; do if [[ $line =~ "potato" ]]; then echo spam; fi; echo $line; done < file.txt > /tmp/outfile.txt