我正在尝试在文件中找到一个模式,然后找到第二个模式,然后在第二个模式之后添加一个带有文本的行。
例如,如果这是我正在尝试更改的文件中的文本:
aaa
bbb
ccc
ddd
eee
fff
ggg
我想匹配“aaa”然后“ddd”,然后在“ddd”之后添加“hello”到该行。
我试过
sed -i "/aaa/,/ddd/a\hello" foo.txt
但我最终得到的是:
aaa
hello
bbb
hello
ccc
hello
ddd
hello
eee
fff
ggg
编辑:另外,有没有办法确保这只发生一次,或者只在第一次出现第二种模式之后(示例中为“ddd”)?
答案 0 :(得分:2)
sed $'/aaa/,/ddd/ { /ddd/ a\hello\n }' patterns
大括号中的命令在匹配ddd的任何行之后添加行hello。但是,大括号中的命令仅适用于aaa和ddd之间的行。
或者,使用替代而不是添加:
sed '/aaa/,/ddd/ s/ddd/ddd\nhello/' patterns
这会产生:
aaa
bbb
ccc
ddd
hello
eee
fff
ggg
此版本的作用是限制替代品仅在aaa行发生后才发生。
备选方案:假设我们只想在第一次出现ddd后添加hello,并且只有在事先发生aaa时才添加。在那种情况下:
sed $'0,/ddd/ {/aaa/,/ddd/ { /ddd/ a\hello\n}}' patterns
第一个范围说明符0,/ddd/
将所有后续范围限制为直到第一次出现的ddd的行。该命令的其余部分与以前一样。
答案 1 :(得分:2)
这可能适合你(GNU sed):
sed '/aaa/,/ddd/!b;/ddd/a\hello' file
编辑:
如果您希望它只在文件中出现一次:
sed 'x;/./{x;b};x;/aaa/,/ddd/!b;/ddd/!b;h;a\hello' file
请参阅John1024解决方案,以优雅地使用Bash和Sed。
N.B。如果可能的话,我会删除这个答案但是SO不允许删除已接受的答案。