我将文本的“块”定义为文件开头,换行符或文件结尾之间的所有行:
block1
block2
block3
anotherblock4
anotherblock5
anotherblock6
lastblock7
lastblock8
任何文字都可以占据一个区块 - 不知道有哪些线条。 我试着编写一个shell脚本在第二个块中插入一个新行,但由于sed不喜欢使用换行符,我在这个sed oneliner上乱砍了:
sed -n "H;\${g;s/\n\n/\nTEST\n\n/2;p}"
这导致:
[newline]
block1
block2
block3
anotherblock4
anotherblock5
anotherblock6
TEST
lastblock7
lastblock8
问题是,它在缓冲区的开头添加了一个换行符(标记为[newline],因为StackOverflow的标记无法显示) 有没有其他方法可以使用不同的工具或不同的正则表达式来完成它?
答案 0 :(得分:2)
这可以满足您的需求,并在开头摆脱不需要的newline
:
sed -n "1{x;d};H;\${g;s/\n\n/\nTEST\n\n/2;p}"
答案 1 :(得分:1)
这是一种可能的解决方案
awk '/^$/{f++}f==2{print "TEST\n";f=0;next}1' file
答案 2 :(得分:0)
好吧,这不是我最骄傲的时刻,但我认为它能做你想要的......也许吧?我无法让sed
做任何有用的事情,因为至少在我的机器上,它不喜欢在s/x/y
替换命令中使用换行符。
# cat blocks block1 block2 block3 anotherblock4 anotherblock5 anotherblock6 lastblock7 lastblock8 # python -c 'import sys,re; print re.sub("(\n\n[\s\S]*?\n)(\n)", "\\1TEST\n\\2", sys.stdin.read(), 1),' < blocks block1 block2 block3 anotherblock4 anotherblock5 anotherblock6 TEST lastblock7 lastblock8
注意:
sed
的“替换第二匹配”选项,所以我需要一个更复杂的正则表达式。.
与换行符不匹配,因此[\s\S]
。?
使*
非贪婪。1
的第4个参数将此限制为单个替换。print
添加额外的换行符。或者,您可以在几乎但不太正确的| tail +2
命令后点击“sed
”来切断第一行输出。
答案 3 :(得分:0)
还有一个awk
解决方案。这要求awk
跟踪段落,而不是像ghostdog74的解决方案那样自己计算段落。
awk -v 'RS=\n\n' '{print}NR==2{print"TEST"}{print""}'