【问题标题】:Grep lines between two patterns, one unique and one repeated两种模式之间的 Grep 线,一种独特,一种重复
【发布时间】:2020-12-01 16:21:03
【问题描述】:

我有一个像这样的文本文件

    1
    bbbbb
    aaa
    END
    2
    ttttt
    mmmm
    uu
    END
    3
    ....
    END

单个数字模式 (1,2,3) 和 END 之间的行数是可变的。所以上限模式改变了,但最后一个没有。使用一些 bash 命令,我想在指定的上层伙伴和相应的 END 之间使用 grep 行,例如将输入 2 作为输入并返回的命令

    2
    ttttt
    mmmm
    uu
    END

我用 sed 和 awk 尝试了各种解决方案,但仍然无法弄清楚。主要问题是我可能需要在文件中间添加一个条目,所以我不能将 sed 与 /pattern/q 一起使用...任何帮助将不胜感激!

【问题讨论】:

    标签: bash awk sed grep


    【解决方案1】:

    对于awk,我们在匹配作为输入参数的起始模式时设置了一个标志f。在该行之后,标志打开并打印每一行。当到达“END”(并且标志打开!)时,它退出。

    awk -v p=2 '$0~p{f=1} f{print} f&&/END/{exit}' file
    

    【讨论】:

    • 谢谢!事实证明,这对我来说是最好的解决方案
    【解决方案2】:

    使用 sed 及其地址仅打印模式之间的文件的一部分:

    #!/bin/bash
    start=x
    while [[ $start = *[^0-9]* ]] ; do
        read -p 'Enter the start pattern: ' start
    done
    sed -n "/^$start$/,/^END$/p" file
    

    【讨论】:

      【解决方案3】:

      您可以将sed 与地址范围一起使用。为方便起见,修改/RE1/,/RE2/中的第一个正则表达式(RE1):

      sed -n '/^[[:space:]]*2$/,/^[[:space:]]*END$/p' file
      

      或者,

      sed '
          /^[[:space:]]*2$/,/^[[:space:]]*END$/!d
          /^[[:space:]]*END$/q
      ' file
      

      这会在阅读END 时退出,因此可能会更有效。

      【讨论】:

        【解决方案4】:

        仅使用 bash 的另一个选项/解决方案

        #!/usr/bin/env bash
        
        start=$1
        
        while IFS= read -r lines; do
          if [[ ${lines##* } == $start ]]; then
            print=on
          elif [[ ${lines##* } == [0-9] ]]; then
            print=off
          fi
          case $print in on) printf '%s\n' "$lines";; esac
        done < file.txt
        

        以数字作为参数运行脚本,1 可以是 2 或 3 或 ...

        ./myscript 1
        

        【讨论】:

          【解决方案5】:

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

          sed -n '/^\s*2$/{:a;N;/^\s*END$/M!ba;p;q}' file
          

          通过设置-n 选项关闭隐式打印。

          收集以2开头的行和以END开头的行结束的行,打印集合并退出。

          注意第二个正则表达式使用M 标志,它允许^$ 在匹配多行时匹配行的开头和结尾。要记住的另一件事是,使用范围即sed -n '/start/,/end/p' file,将在满足第一个条件的那一刻开始打印行,如果第二个匹配没有实现,它将继续打印到文件末尾。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-09-28
            • 2012-11-19
            • 2013-12-13
            • 1970-01-01
            • 2014-04-12
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多