【问题标题】:Inserting a line to a known block of text在已知文本块中插入一行
【发布时间】:2010-11-08 21:29:24
【问题描述】:

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

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 的标记无法显示它) 还有其他方法可以使用不同的工具或不同的正则表达式吗?

【问题讨论】:

    标签: regex bash sed


    【解决方案1】:

    这会做你想做的,并在开始时摆脱不需要的newline

    sed -n "1{x;d};H;\${g;s/\n\n/\nTEST\n\n/2;p}"
    

    【讨论】:

      【解决方案2】:

      这是一种可能的解决方案

      awk '/^$/{f++}f==2{print "TEST\n";f=0;next}1' file
      

      【讨论】:

        【解决方案3】:

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

        #个猫块 块1 块2 块3 另一个块4 另一个块5 另一个区块6 最后一个块7 最后一个块8 # python -c 'import sys,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 的“替换 2nd 匹配”选项等效的选项,所以我需要一个更复杂的正则表达式。
        • . 不匹配换行符,因此 [\s\S]
        • ? 使 * 不贪婪。
        • 1 的第四个参数将其限制为单个替换。
        • 末尾的逗号禁止 print 添加额外的换行符。

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

        【讨论】:

        • 你的意思是'|尾巴-c +2'?这是我目前的解决方法。我正在考虑让自己更好地学习 sed 和 bash。
        【解决方案4】:

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

        awk -v 'RS=\n\n' '{print}NR==2{print"TEST"}{print""}'
        

        【讨论】:

        • 也提出了这个解决方案,但它会在最后一个块添加一个换行符,并且有人(我认为是作者)对此发表了评论。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-10-19
        • 1970-01-01
        • 1970-01-01
        • 2013-12-14
        相关资源
        最近更新 更多