【问题标题】:How to use cut lines based on a pattern match?如何使用基于模式匹配的切割线?
【发布时间】:2017-11-16 11:48:37
【问题描述】:

我有一个输出如下的文件

--B32934--
descr:     X
descr:     Y
descr:     Z
--B20484
descr:     A
descr:     B
descr:     C
--B41946
descr:     1
descr:     2
descr:     3
descr:     4

我只需要 --BXXXX 数字和第一行,其余行需要从文件中删除。是否可以根据模式匹配--B 删除行 >1?

例如在“--B32934”下我只想要“descr:X”。其余行需要删除。

想要的结果应该是这样的

--B32934--
descr:     X

【问题讨论】:

  • 发布想要的结果
  • 您好,感谢您的回复。所需的结果应如下所示 --B32934-- descr: X --B20484 descr: A --B41946 descr: 1
  • 在问题中编辑附加信息。在 cmets 中阅读太难了。请注意,顶部有用于格式化的精美按钮。

标签: awk sed


【解决方案1】:

这是grep 的另一个解决方案

grep -e '^--B[0-9]\+' --no-group-separator -A 1 file

输出:

--B32934--
descr:     X
--B20484
descr:     A
--B41946
descr:     1

【讨论】:

  • 谢谢,有什么办法可以在每次输出后添加一个新的空行?
  • @venkyjack 是的,只需使用grep -e '^--B[0-9]\+' -A 1 --group-separator "" file
【解决方案2】:

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

sed '/^--B\S\+/!d;n' file

删除任何不以--B 开头且后跟一个或多个非空格字符的行。否则打印该行和以下内容。

【讨论】:

    【解决方案3】:

    两种方法:

    -- awk 方法:

    awk '/^--B[0-9]+/{ r=NR; print }(NR-1)==r' file
    
    • /^--B[0-9]+/ - 如果行以 pattern

    • 开头
    • r=NR - 持有记录号

    • (NR-1)==r - 如果是模式行之后的下一行

    要在模式行之后捕获以下 2 行 - 使用此方法:

    awk '/^--B[0-9]+/{ r=NR; print }(NR-1)==r || (NR-2)==r' file
    

    -- GNU sed 方法:

    sed -n '/--B[0-9]*/{N;p;}' file
    
    • N - 向模式空间添加换行符,然后将下一行输入附加到模式空间(GNU 扩展)

    输出(两种方法):

    --B32934--
    descr: X
    --B20484
    descr: A
    --B41946
    descr: 1
    

    【讨论】:

    • 抱歉,我有点 sed,当我在我的 mac 上尝试这个时,我得到下面的错误 sed -n '/--AS[0-9]*/{h;N ;p}' test sed: 1: "/--AS[0-9]*/{h;N;p}": p 命令末尾的多余字符
    • @venkyjack,它是 GNU sed。如果是这样,请使用我的 awk 方法
    • awk 命令可以在我的 mac 上运行,但只是为了我的信息,您能否告诉我 $0 和 B[0-9] 的作用?谢谢。我问是因为如果我需要 2 行,我需要知道需要修改什么。
    • @RomanPerekhrest 只需添加 ; 即可结束使用这两个 sed 版本...如果您使用的是[0-9]*,您不妨删除它...并且不需要h,因为嗯...sed -n '/--B/{N;p;}'...也可以使用grep -A1 --no-group-separator '\--B',但需要GNU grep
    • @venkyjack,查看我的详细信息
    【解决方案4】:

    您可以使用以下awk 命令:

    awk 'p{print;p=0}/^-/{print;p=1}' file
    

    解释:

    如果变量p 为真,则打印当前行,将p 设置回0(假)。如果该行以- 开头,则打印当前行并将p 设置为1 (true)(以便打印下一行)。

    【讨论】:

    • 谢谢。这也有效,但如果我需要 2 行而不是 1 行,我要修改什么变量?
    • @venkyjack 请参阅 stackoverflow.com/questions/17908555/… 了解您可以做的各种事情...awk '/^-/{p=3} p && p--' 将是匹配行的一种方式,然后是 2
    • @Sundeep 谢谢,有什么办法可以在每次输出后添加一个空白的新行吗?
    • 将输出记录分隔符设置为两个换行符:awk 'p{print;p=0}/^-/{print;p=1}' ORS='\n\n' file
    • @hek2mgl 谢谢,但这会在 B 和 descr: 之间添加额外的空行,我只需要在每组 B 和 descr: 之间添加:例如:--B32934-- descr: X descr: Y 描述:Z --B20484 描述:A 描述:B 描述:C
    猜你喜欢
    • 1970-01-01
    • 2013-08-19
    • 1970-01-01
    • 1970-01-01
    • 2022-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-16
    相关资源
    最近更新 更多