【问题标题】:How to use sed/awk to extract text between two patterns when a specific string must exist in the text block当文本块中必须存在特定字符串时,如何使用 sed/awk 在两个模式之间提取文本
【发布时间】:2020-02-13 04:03:52
【问题描述】:

我已经找到了几个关于如何在两种模式之间进行 sed/awk 的答案,但我还需要只找到其中​​包含字符串的特定文本块!

文字示例:

<requirement        id = "blabla.1"
                slogan = "Handling of blabla"
          work-package = "bla444.2"
          logical-node = "BLA-C"
                 level = "System"
>
Bla bla.
</requirement>
<requirement        id = "bla.2"
                slogan = "Reporting of blabla"
          work-package = "bla444.1"
          logical-node = "BLA-C"
                 level = "System"
>
Bla bla bla.
</requirement>

所以我们的目标是只获取 & 之间的文本块,它应该在工作包中包含 bla444.1!这应该在示例中只给我最后一个文本块。当然,我想要 sed 的文件有更多要求,并且有几个需要工作包,所以不仅仅是 sed 会找到的最后一个文本块。

sed -e 's/<requirement\(.*\)<\/requirement/\1/' file

上面的 sed 行会给出所有的文本块(要求)。

一件事是文本块没有固定的行数,但都会有工作包!

【问题讨论】:

    标签: awk sed


    【解决方案1】:

    请您尝试关注一下。

    awk '
    /^<requirement/{
      if(found && value){
        print value
      }
      found=value=""
    }
    {
      value=(value?value ORS:"")$0
    }
    /work-package.*bla444.1\"$/{
      found=1
    }
    END{
      if(found && value){
        print value
      }
    }
    '  Input_file
    

    说明:为上述代码添加详细说明。

    awk '                           ##Starting awk program from here.
    /^<requirement/{                ##Checking condition if line starts from string <requirement then do following.
      if(found && value){           ##Checking condition if found and value is NOT NULL then do following.
        print value                 ##Printing value(which contains all blocks value, explained further code) here.
      }
      found=value=""                ##Nullifying variables found and value variables here.
    }
    {
      value=(value?value ORS:"")$0  ##Creating variable value whose value is keep concatenating its own value each time cursor comes here.
    }
    /work-package.*bla444.1\"$/{    ##Checking condition if a line has string work-package till bla444.1 then do following.
      found=1                       ##Making variable found and setting value to 1, kind of FLAG enabling stuff.
    }
    END{                            ##Starting END block of this awk code here.
      if(found && value){           ##Checking condition if found and value is NOT NULL then do following.
        print value                 ##Printing value variable here.
      }
    }
    '  Input_file                   ##Mentioning Input_file name here.
    

    【讨论】:

    • 这确实有效!我如何更改它以找到仅具有 bla444 的工作包,因为我有很多来自 bla444、bla444.1...x 的工作包?
    • 好的,我想通了:awk '/^&lt;requirement/{if(found &amp;&amp; value){print value};found=value=""} {value=(value?value ORS:"")$0} /work-package.*bla444.*\"$/{found=1} END{if(found &amp;&amp; value){print value}}' file。这将提供所有带有 bla444、bla444.1...x 的工作包
    • @FotisK,对不起,我离开了系统,很酷很高兴听到你想通了,干杯 :)
    【解决方案2】:

    这可能对你有用(GNU sed):

    sed -n '/<requirement/{:a;N;/<\/requirement/!ba;/work-package = "bla444\.1"/p}' file
    

    过滤&lt;requirement&lt;/requirement&gt; 之间的行,如果这些行包含字符串work-package = "bla444.1",则打印集合。

    或许:

    sed -ne '/<requirement/{' -e ':a' -e 'N' -e '/<\/requirement/!ba' -e '/work-package = "bla444\.1"/p' -e '}' file
    

    或者:

    cat <<\! | sed -nf - file
    /<requirement/{
    :a
    N
    /<\/requirement/!ba
    /work-package = "bla444\.1"/p
    }
    !
    

    【讨论】:

    • 这对我不起作用,我认为是由于不同系统上的 sed 版本不同。 &gt; sed -n '/&lt;requirement/{:a;N;/&lt;\/requirement/;/work-package = "bla444\.1"/p}' file 带有错误消息:sed: -e expression #1, char 37: unknown command: ;'`
    • @FotisK 也许您的 sed 版本不理解命令分隔符 ; 在这种情况下,每个命令都可以分隔为 -e 选项,请参阅编辑。或者写入一个文件commandFile,每个命令在一个单独的行上并调用sed -nf commandFile file
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-14
    • 2015-11-10
    • 2012-11-03
    • 2022-11-13
    • 1970-01-01
    • 2018-06-20
    相关资源
    最近更新 更多