![如何使用 sed 在多行匹配后插入一些文本?](https://linux22.com/image/158363/%E5%A6%82%E4%BD%95%E4%BD%BF%E7%94%A8%20sed%20%E5%9C%A8%E5%A4%9A%E8%A1%8C%E5%8C%B9%E9%85%8D%E5%90%8E%E6%8F%92%E5%85%A5%E4%B8%80%E4%BA%9B%E6%96%87%E6%9C%AC%EF%BC%9F.png)
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
为#]
。