我尝试使用sed在[Block B]之后的以下文件中插入一行:
[Block A]
line 1
line 2
[Block B]
line 1
line 2
[Block C]
line 1
line 2
我使用的命令:
sed '/\[Block B\]/,/^$/a\inserted line' file
正确/期望的结果应该是:
[Block B]
line 1
line 2
inserted line
然而,我得到了这个:
[Block B]
inserted line
line 1
inserted line
line 2
inserted line
请告诉我如何使用sed获得所需的结果。谢谢!
答案 0 :(得分:12)
sed -e '/\[Block B\]/{:a;n;/^$/!ba;i\inserted line' -e '}'
答案 1 :(得分:6)
我在寻找自己问题的解决方案时发现了这个问题,这个问题类似但有点不同。我在这里修改了答案以解决我的问题。
我需要在配置文件中的块末尾插入一些文本,如下所示:
name1 {
...
}
name2 {
...
inserted text line 1
inserted text line 2
}
name3 {
....
}
为了达到这个目的,我从上面拿了@toyntz评论并对其进行了调整:
/^name2 {/,/^}/{
/^}/i\ inserted text line 1
/^}/i\ inserted text line 2
}
这只是sed的表达;它可以放在一个文件中并使用sed -f
执行,如下所示:
$ sed -f sed_expression data_file
此第一个表达式搜索以name2 {
开头的行开头,这些行出现在行的开头,并以}
结尾也出现在行的开头。选择要处理的块。其余表达式括在{
花括号}
中,并在所选范围内运行。它包含我们希望插入的每行一个命令,每个命令都带有一个表达式/^}/
,该表达式匹配具有结束大括号的行,后跟插入i
操作以插入一行文本。 i
之后是\
,因此也会插入前导空格。
然后我进一步使用了表达式,用一个替换了两个insert命令:
/^name2 {/,/^}/{
/^}/i\
inserted text line 1\
inserted text line 2
}
这里,一个命令插入的文本分布在以下两行中。请注意第一行上的附加尾随\
以继续单个命令。
接下来,我把它减少到一行。它使它变得混乱和难以阅读,但它仍然有效:
/^name2 {/,/^}/{/^}/i\ inserted text line 1\n inserted text line 2
}
要插入的两行由换行符\n
分隔。精明的读者会注意到那里实际上有两条线 - 你不能把右支撑放在第一条线的末端;这就是为什么上面的其他答案都有第二个表达式。所以,上面是我能做的最好的。要在bash命令行上表示:
sed -e '/^name2 {/,/^}/{/^}/i\ inserted text line 1\n inserted text line 2' -e '}' data_file
我已经写出了这个简写,希望它能解释给那些希望在文本块的末尾插入如何编写sed表达式来实现它的人。 Sed表达式可能非常神秘,难以弄清楚 - 希望我的解释在这方面有所帮助。
答案 2 :(得分:0)
这可能适合你(GNU sed):
sed '/^\[Block B\]/,/^$/!b;/^$/i\inserted line' file