【问题标题】:How to get text between two patterns in awk?如何在awk中获取两个模式之间的文本?
【发布时间】:2014-05-27 00:28:55
【问题描述】:

给出这个 input.txt:

START asd
blah
blah
blah

START HELLO
lorem
ipsum
dolor 
sit
amet

START STACK
bleh
bleh

我正在尝试找出START HELLOSTART STACK 之间的界限。

所以这是想要的输出

START HELLO
lorem
ipsum
dolor 
sit
amet

我做了这个 awk:

awk '/START/{l++} {if(l==2){exit;} if(l==1) {print}}' input.txt

但返回第一个 START 块,而不是 START HELLO

START asd
blah
blah
blah

你有什么想法让它尽可能清晰吗?几天前我刚开始使用 awk,因此任何提示、帮助或建议将不胜感激。

【问题讨论】:

  • 如果START HELLOSTART STACK 块之间还有另一个块,您是否也希望打印它?对于解决方案来说,了解您是因为点击了START STACK,还是因为点击了START <anything>,或者因为您点击了一个空行,这一点很重要。

标签: regex bash awk


【解决方案1】:

空行很方便:您可以使用“段落”模式,其中每个 awk 记录由空行而不是换行符分隔:

awk -v RS="" '/^START HELLO/' file

如果“hello”作为参数传入:

awk -v RS="" -v start=HELLO '$1 == "START" && $2 == start' file

【讨论】:

    【解决方案2】:

    如果您需要在START HELLOSTART STACK 之间指定,无论空格段落如何:

    awk '/START HELLO/ {f=1} /START STACK/ {f=0} f;' file
    START HELLO
    lorem
    ipsum
    dolor
    sit
    amet
    

    这将是对该问题的更准确的答案:(如果您需要多个部分,则更好)

    I'm trying to get the lines between START HELLO and START STACK.   
    

    我通常会向 Glenn 寻求解决方案,但问题并非如此

    awk -v RS="" '/^START HELLO/' file
    

    【讨论】:

      【解决方案3】:

      您的索引已关闭。只需将您的 awk 更改为:

      awk '/START/{l++} {if(l==3){exit;} if(l==2) {print}}' input.txt
      

      【讨论】:

        【解决方案4】:

        打印以“START HELLO”开头的空行分隔块:

        awk -v RS= '/^START HELLO/' file
        

        要打印“START HELLO”和以“START”开头的下一行之间的文本:

        awk '/^START HELLO{f=1} f{if (/^START/) exit; else print}' file
        

        要打印“START HELLO”和以“START STACK”开头的下一行之间的文本:

        awk '/^START HELLO{f=1} f{if (/^START STACK/) exit; else print}' file
        

        如果您都在考虑使用getline 的解决方案,那么这可能是错误的方法,因此请确保您阅读http://awk.info/?tip/getline 并在做出决定之前充分了解适当的用途和所有注意事项。

        【讨论】:

          【解决方案5】:

          我认为这可能会解决您的问题:

          awk '/START HELLO/{print;while(getline)if($0 !~/START STACK/)print;else exit}' input.txt
          

          【讨论】:

          • 没有。绝对不行。不要这样做!这甚至不接近如何使用 awk。这是以前从未见过 awk 脚本的人可能会考虑尝试解决问题的方式。请参阅任何其他答案以获得更好的方法。
          • @EdMorton 嗨,我不清楚使用 getline 的注意事项,你能帮忙解释一下吗?至于您在link 中的应用建议,我认为这不符合警告:awk '/^START HELLO/{print;getline;while(1)if ($0 ~/^START STACK/) exit; else {print;getline}}' input.txt
          • 几个例子:尝试修改你的脚本以将包含“foo”的每一行打印到标准错误以进行调试。请注意,对于这样一个微不足道的增强,您需要在 3 个不同的地方添加相同的测试或重新编写您的脚本,这与所有在 1 个地方进行微不足道的调整的非 getline 解决方案不同。如果你的输入文件在你的脚本运行时被 zapped 会发生什么?您的脚本将进入一个无限循环,这与其他会优雅终止的脚本不同。在使用getline之前阅读并充分理解awk.info/?tip/getline的全部内容。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-09-28
          • 2013-08-21
          • 2023-01-13
          • 2012-11-22
          • 2021-06-20
          • 2017-07-15
          相关资源
          最近更新 更多