2

我将文本“块”定义为文件开头、换行符或文件结尾之间的所有行:

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 的标记无法显示它)是否有另一种方法可以使用不同的工具或不同的正则表达式来做到这一点?

4

4 回答 4

2

这可以满足您的需求,并newline在一开始就摆脱不需要的东西:

sed -n "1{x;d};H;\${g;s/\n\n/\nTEST\n\n/2;p}"
于 2009-07-08T04:26:51.253 回答
1

这是一种可能的解决方案

awk '/^$/{f++}f==2{print "TEST\n";f=0;next}1' file
于 2009-07-08T01:21:13.577 回答
0

好吧,这不是我最自豪的时刻,但我认为它如你所愿......也许吧?我无法sed做任何有用的事情,因为至少在我的机器上,它不喜欢在s/x/y替换命令中使用换行符。

# 猫块
块1
块2
块3

另一个块4
另一个块5
另一个区块6

最后一个块7
最后一个块8
# python -c '导入系统,re; 打印 re.sub("(\n\n[\s\S]*?\n)(\n)", "\\1TEST\n\\2", sys.stdin.read(), 1), ' < 块
块1
块2
块3

另一个块4
另一个块5
另一个区块6
测试

最后一个块7
最后一个块8

笔记:

  • 没有等效的sed“替换第二场比赛”选项,所以我需要一个更复杂的正则表达式。
  • .不匹配换行符,因此[\s\S].
  • 使?*贪婪。
  • 的第 4 个参数将其1限制为单个替换。
  • 末尾的逗号禁止print添加额外的换行符。

或者,您可以| tail +2在几乎但不完全正确的sed命令之后添加“”以切断第一行输出。

于 2009-07-08T01:20:35.667 回答
0

另一种awk解决方案。这要求awk跟踪段落,而不是像 ghostdog74 的解决方案那样自己计算它们。

awk -v 'RS=\n\n' '{print}NR==2{print"TEST"}{print""}'
于 2009-07-08T15:17:24.507 回答