【问题标题】:filter out a substring from a string in linux only once在linux中只过滤一次字符串中的子字符串
【发布时间】:2014-07-24 15:26:23
【问题描述】:

我正在尝试从我在 linux 中使用 sed 命令的字符串中提取特定的子字符串。但是,问题是在命令第一次返回子字符串后,我再次在字符串中查找起始关键字。

我想跳过最后一部分。我只想要关键字之间的第一个子字符串。

字符串:bhaskar.txt

bhaskar
rahul
gaurav
ganesh
bhaskar
rahul

需要子字符串:“bhaskar”和“ganesh”之间的所有内容

使用的命令:sed -n '/bhaskar/,/ganesh/p' bhaskar.txt

输出:

bhaskar
rahul
gaurav
ganesh
bhaskar
rahul

预期输出:

bhaskar
rahul
gaurav
ganesh

【问题讨论】:

    标签: linux sed substring


    【解决方案1】:

    在 awk 中可以这样做:

    awk '/bhaskar/ && !p++, /ganesh/' bhaskar.txt
    

    /bhaskar/ 第一次匹配时,p 尚未定义,所以!p 为真,范围开始。 p++ 表示检查完值后,将 p 加 1。范围将持续到 /ganesh/ 匹配。

    第一个范围完成后,如果/bhaskar/ 再次匹配,p 将为正,因此!p 将评估为 false,范围不会重新启动。

    输出:

    bhaskar
    rahul
    gaurav
    ganesh
    

    这是另一种你可以做到的方式,有些人可能更喜欢:

    awk '/bhaskar/ {p=1} p {print} /ganesh/ {exit}' bhaskar.txt
    

    可以说更不言自明,它会在/bhaskar/ 匹配时设置变量p,在设置变量p 时打印,并在/ganesh/ 匹配时退出(打印后)。

    【讨论】:

      【解决方案2】:

      使用awk

      awk -v a=bhaskar -v b=ganesh '$0 == a { p = 1; t = "" }; $0 == b && p { printf "%s%s\n", t, b; p = 0 }; p { t = t $0 ORS }' file
      

      输出:

      bhaskar
      rahul
      gaurav
      ganesh
      

      【讨论】:

        【解决方案3】:

        使用 sed,你需要使用循环:

        sed -n '/bhaskar/{: loop; p; /ganesh/q; n; b loop}' bhaskar.txt
        

        转念一想,并非如此,您只需要在范围结束时退出:

        sed -n '/bhaskar/,/ganesh/p; /ganesh/q'
        

        【讨论】:

          猜你喜欢
          • 2018-09-28
          • 1970-01-01
          • 2018-04-02
          • 2021-06-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-02-10
          • 1970-01-01
          相关资源
          最近更新 更多