代码之家  ›  专栏  ›  技术社区  ›  Nick Bull

sed范围和删除最后一个匹配行

  •  3
  • Nick Bull  · 技术社区  · 7 年前

    我有这个数据:

    One
      two
      three
    Four
      five
      six
    Seven
      eight
    

    这个命令:

    sed -n '/^Four$/,/^[^[:blank:]]/p'
    

    我得到以下输出:

    Four
      five
      six
    Seven
    

    如何更改此sed表达式以使其与输出的最后一行不匹配?所以理想的输出应该是:

    Four
      five
      six
    

    我试过很多感叹号的方法,但都没能成功。

    6 回复  |  直到 7 年前
        1
  •  4
  •   anubhava    7 年前

    你可以用管子接另一个 sed 跳过最后一行:

    sed -n '/^Four$/,/^[^[:blank:]]/p' file | sed '$d'
    

    Four
      five
      six
    

    或者,您可以使用:

    sed -n '/^Four$/,/^[^[:blank:]]/{/^Four$/p; /^[^[:blank:]]/!p;}' file
    
        2
  •  7
  •   Casimir et Hippolyte    7 年前

    使用“do..while()”循环:

    sed -n '/^Four$/{:a;p;n;/^[[:blank:]]/ba}'
    

    细节:

    /^Four$/ {
        :a         # define the label "a"
        p          # print the pattern-space
        n          # load the next line in the pattern space
        /^[[:blank:]]/ba # if the pattern succeeds, go to label "a"
    }
    
        3
  •  2
  •   Ed Morton    7 年前

    你用错工具了。sed是用来做s/旧/新的,仅此而已。使用awk:

    $ awk '/^[^[:blank:]]/{f=/^Four$/} f' file
    Four
      five
      six
    

    工作原理:每次找到不以空格开头的行( /^[^[:blank:]]/ )它树立了一面旗帜 f (对于“found”)为1,如果该行以 Four 否则为0( f=/^Four$/ )无论何时 f 是非零的,被解释为真条件,因此调用awks的默认行为,即打印当前行。所以当它击中一个从四开始的方块时,它会打印出该方块中的每一行,因为 f 为1/真,并且对于其他块,它不会打印,因为 f 是0/假。

        4
  •  1
  •   RavinderSingh13 Nikita Bakshi    7 年前

    跟随 awk 也许能帮到你。

    awk '!/^ /{flag=""} /Four/{flag=1} flag'   Input_file
    

    输出如下。

    Four
      five
      six
    

    另外,如果需要将输出保存到input_文件中,请附加 > temp_file && mv temp_file Input_file 以上代码。

        5
  •  0
  •   MiniMax    7 年前
    grep -Pzo '\n\KFour\n(\s.+\n)+' input.txt
    

    产量

    Four
      five
      six
    
        6
  •  0
  •   potong    7 年前

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

    sed '/^Four/{:a;n;/^\s/ba};d' file
    

    如果一行以 Four 打印它和以空格开头的任何后续行。

    另一种方式:

    sed '/^\S/h;G;/^Four/MP;d' file
    

    如果行以非空格开头,请将其复制到保留空格(hs)。将hs附加到每一行,如果每一行以 打印第一行并删除其余行。这将删除除以 .