如何使用 sed 在多行匹配后插入一些文本?

如何使用 sed 在多行匹配后插入一些文本?

sample.txt我有一个这样的文件:

lots of text
lots of text


#nvram = [
#   these
#   could
#   be,
#   anything
#]

lots of text
lots of text

我想添加一些文本“foobar”来得到这个:

lots of text
lots of text


#nvram = [
#   these
#   could
#   be,
#   anything
#]
foobar

lots of text
lots of text

我查看了一些相关的线程并尝试了很多东西,但无法以正确的方式将信息连接在一起。

多行匹配: 如何使用 sed 或 ex 将块(多行代码)替换为新的文本块(代码)? https://stackoverflow.com/questions/11234001/replace-multiple-lines-using-sed 如何使用 sed 替换多行字符串?

附加: 如何使用 sed 在“test message1”之后添加新行?

我一直在尝试这样的事情:

sed  '/^#nvram = \[$/{
    N
    ^.*$
}/abc123/' sample.txt

sed '/^#nvram = \[$/ {N; s/\<^#nvram = \[$\>\n<^.*$\>/abc123/g}' sample.txt

sed '/^#nvram = \[$/ {N; s/\<#nvram = \[\>\n\<.*\>/abc123/g}' sample.txt

sed '/^#nvram = \[$/ {N; s/#nvram = \[\n.*/abc123/g}' sample.txt

sed '/^#nvram = \[$/ {N; /#nvram = \[\n.*/abc123/a}' sample.txt

sed '/^#nvram = \[$/ {N; /#nvram = \[(\n.*){1,}/abc123/a}' sample.txt


sed '/^#nvram = \[$/!b;n;cABC' sample.txt

sed '/^#nvram = \[$/N;cABC' sample.txt

sed '/^#nvram = \[$/N/#\]/a;cABC' sample.txt


sed '/^#nvram = \[$/,/#\]/{/^#nvram = \[$/n;/#\]/!{s/./abc/g}}' sample.txt

sed '/^#nvram = \[$/,/#\]/{/^#nvram = \[$/n;/#\]/!{/abc/a}}' sample.txt

sed '/^#nvram = \[$/,/#\]/{/^#nvram = \[$/n;/#\]/!/a abc}' sample.txt

sed '/^#nvram = \[$/,/#\]/{/^#nvram = \[$/n;/#\]/;/a abc}' sample.txt

sed '/^#nvram = \[$/,/#\]/{/^#nvram = \[$/n;/#\]/a abc}' sample.txt


但到目前为止我还没有成功。

答案1

使用循环怎么样?

sed '/^#nvram = \[/{
:a                          
N                                                  
/\n#\]/!ba                                                                  
a\
foobar
}
' sample.txt

解释:

:a              # begin loop
N               # append next line to pattern space
/\n#\]/!ba      # if we haven't matched the end marker yet, branch back to a
a\              # append after loop exits
foobar

至少在 GNU sed 中,这可以写成一行代码

sed -e '/^#nvram = \[/{:a; N; /\n#\]/!ba; a\foobar' -e '}' sample.txt

答案2

使用 GNU sed 可以-z

$ sed -z 's/#nvram = \[.*\]/&\nfoobar\n/' file
lots of text
lots of text


#nvram = [
#   these
#   could
#   be,
#   anything
#]
foobar

lots of text
lots of text

您可能需要调整正则表达式,具体取决于“任何内容”的真正含义(例如它是否可以包含])以及文件中是否有其他类似的块。

这会更加强大,例如,如果anything不包含]s 并且您的输入中有其他类似的块:

sed -z 's/#nvram = \[[^]]*\]/&\nfoobar\n/' file

答案3

我将选择您采用的一种方法,并向您展示如何使其发挥作用,以便它引起您的共鸣并留在您身边:

$ sed -e '
   /^#nvram = \[$/,/^#]$/!b
   /^#]$/a\
Foobar
' sample.txt

我个人不喜欢上面的做法,并采取了一些不同的做法:

$ sed -e '
   /^#nvram = \[$/,/^#]$/!b
   /^#]$/G
   s/\n/&Foobar/
' sample.txt

答案4

这也是一个简单的 sed:

sed '/#nvram = \[/,/#]/ s/#]/#]\nfoobar/' file

它找到发生了 的行#nvram = [,然后查找该行之后的所有行,直到#]解决第一次出现的 an 为止,然后将 替换#]\nfoobar#]

相关内容