【问题标题】:SED or AWK command to print only lines that are between two set patternsSED 或 AWK 命令仅打印两个设置模式之间的行
【发布时间】:2013-03-12 22:22:27
【问题描述】:

我需要一个命令/脚本来获取 CVS 合并冲突。基本上,我需要一个 SED 或 AWK 命令来仅打印两个设置模式之间的行

例子:

Pattern1="RCS file:"
Pattern2="conflicts during merge"

当我尝试一个简单的 SED 命令时:

sed -n '/RCS file:/,/conflicts during merge /p' INPUT.txt

我没有得到预期的输出。我只想捕获“filename2 和 filename3”的详细信息(在合并期间发生冲突)。

有人可以帮忙吗?

INPUT.txt

RCS file: /hello/filename1
retrieving revision 1.4.2.1.18.2.2.1
retrieving revision 1.4.2.1.18.2.2.1.4.2
Merging differences between 1.4.2.1.18.2.2.1 and 1.4.2.1.18.2.2.1.4.2 into filename1

RCS file: /hello/filename2
retrieving revision 1.4.2.1.18.2.2.1
retrieving revision 1.4.2.1.18.2.2.1.4.2
Merging differences between 1.4.2.1.18.2.2.1 and 1.4.2.1.18.2.2.1.4.2 into filename2
rcsmerge: warning: conflicts during merge

RCS file: /hello/filename3
retrieving revision 1.6.18.1.2.1.2.1
retrieving revision 1.6.18.1.2.1.2.1.4.3
Merging differences between 1.6.18.1.2.1.2.1 and 1.6.18.1.2.1.2.1.4.3 into filename3
rcsmerge: warning: conflicts during merge

RCS file: /hello/filename4
retrieving revision 1.4.2.1.18.2.2.1
retrieving revision 1.4.2.1.18.2.2.1.4.2
Merging differences between 1.4.2.1.18.2.2.1 and 1.4.2.1.18.2.2.1.4.2 into filename4

(Expected) OUTPUT.txt

RCS file: /hello/filename2
retrieving revision 1.4.2.1.18.2.2.1
retrieving revision 1.4.2.1.18.2.2.1.4.2
Merging differences between 1.4.2.1.18.2.2.1 and 1.4.2.1.18.2.2.1.4.2 into filename2
rcsmerge: warning: conflicts during merge

RCS file: /hello/filename3
retrieving revision 1.6.18.1.2.1.2.1
retrieving revision 1.6.18.1.2.1.2.1.4.3
Merging differences between 1.6.18.1.2.1.2.1 and 1.6.18.1.2.1.2.1.4.3 into filename3
rcsmerge: warning: conflicts during merge

【问题讨论】:

    标签: shell awk sed ksh hp-ux


    【解决方案1】:

    您的sed 命令在看到“RCS 文件”时开始输出,并在看到“冲突”标记时停止。所以它几乎输出了所有东西。用 sed 可以做你想做的事,但它很复杂。 awk 要简单得多:

    awk -v RS= '/conflicts/ {print $0}' INPUT.txt 
    

    使用 awk 的记录概念,用空行分隔它们,并且实质上 grep 每条记录。所以这不会打印两个模式之间的行,而是打印与特定模式匹配的每个行块。

    【讨论】:

    • 当我尝试 AWk 命令时,我得到以下错误...
      awk: Input line RCS file: /was_apps/ cannot be long than 3,000 bytes.
    【解决方案2】:

    这里有提示:

    awk '{if ($1=="HO") i=1}; {if ($1=="JOU") i=0}; i{print}' file
    

    例子:

    $ cat file
    HI
    HO
    JE
    JOU
    LA
    

    所以,

    Pattern1="HO"
    Pattern2="JOU"
    awk -v p1=${Pattern1} -v p2=${Pattern2} '{if ($1==p1) i=1}; {if ($1==p2) i=0}; i{print}' file
    HO
    JE
    

    根据您的情况,

    Pattern1="RCS file:"
    Pattern2="conflicts during merge"
    
    $ awk -v p1=$(Pattern1) -v p2=${Pattern2} '{if ($1==p1) i=1}; {if ($1==p2) i=0}; i{print}' file
    

    编辑

    如果你想查找包含这个文本的字符串,你可以这样做:

    Pattern1="RCS file:"
    Pattern2="conflicts during merge"
    
    $ awk -v p1=$(Pattern1) -v p2=${Pattern2} '{if ($1 ~ p1) i=1}; {if ($1 ~ p2) i=0}; i{print}' file
    

    【讨论】:

    • 这完全符合提交者的要求,但不是他想要的。它会在看到第一个模式时开始打印,但直到它到达消息的末尾才知道是否应该打印它。
    • 是的,现在我看到了@evilotto。我已经更新了我的答案,以便考虑到 contains 这个文本行。
    【解决方案3】:

    兄弟,

    使用 egrep .....它很简单,无需担心 SED 和 AWK。 它是您想要的固定线条图案....

     egrep +B4 conflict INPUT.txt   
    

    here B 选项打印匹配前的 4 行以及匹配模式的行(我使用 GNU egrep)

    egrep 输出:

    RCS file: /hello/filename2
    retrieving revision 1.4.2.1.18.2.2.1
    retrieving revision 1.4.2.1.18.2.2.1.4.2
    Merging differences between 1.4.2.1.18.2.2.1 and 1.4.2.1.18.2.2.1.4.2 into filename2
    rcsmerge: warning: conflicts during merge
    --
    RCS file: /hello/filename3
    retrieving revision 1.6.18.1.2.1.2.1
    retrieving revision 1.6.18.1.2.1.2.1.4.3
    Merging differences between 1.6.18.1.2.1.2.1 and 1.6.18.1.2.1.2.1.4.3 into filename3
    rcsmerge: warning: conflicts during merge
    

    【讨论】:

      【解决方案4】:

      给你:

      sed -n '/RCS file:/ !{H;d}; /RCS file:/ {x; /conflict/p}; $ {x; /conflict/p}' input.txt
      

      对于与“RCS 文件:”不匹配的每一行 - 将其附加以保留空间。如果它匹配该行(或者是文件的结尾) - 将模式空间与保持空间交换并检查它是否匹配'conflit'。如果有,请打印。

      如果我们使用分支会更简单。

      像这样:

      sed -n '$ba; /RCS file:/ba; H; d; :a; x; /conflict/p' input.txt
      

      【讨论】:

      • sed -n '/^$/!{H;$!d};x;/conflicts during merge$/p'
      • sed: 函数 /RCS 文件:/ !{H;d}; /RCS 文件:/ {x; /冲突/p}; $ {x; /conflict/p} 无法解析。
      • @jthill
        当我运行 SED 命令时,我收到以下错误...
      • 这可能是 sed 的 hpux 版本的限制。您可以尝试将 sed 脚本写入文件(用换行符替换所有分号)然后使用 -f 键运行它,如下所示:sed -n -f my_script.sed input.txt
      • 我找到了 HP-UX sed 的联机帮助页,但没有看到分号。所以它要么是一个多行文件,要么是多个-e 参数。像这样:sed -n -e'/^$/!{H' -e'$!d' -e'}' -ex -e'/conflicts during merge$/p' input.txt