【问题标题】:grep for second word from the surrounding lines of first wordgrep 从第一个单词的周围行中获取第二个单词
【发布时间】:2011-03-03 15:03:23
【问题描述】:

我有一个这样的文件:

ABC1  OBJECT-TYPE
...
...
KEY { XYZ1 }
...
...

ABC2  OBJECT-TYPE
...
...
ABC3  OBJECT-TYPE
...
...
KEY { XYZ3 }
...
...

我的第一个搜索词是 KEY(因为它在文件中出现的次数较少),第二个搜索词是 OBJECT-TYPE。 OBJECT-TYPE 可以出现在 KEY 行上方的几行(可能是 5 或 10)。如果在文件中找到 KEY,我需要具有键值和相应对象类型值的输出。

一模一样:

ABC1 KEY1

ABC2 KEY2

【问题讨论】:

  • 请将问题中的“类似”部分替换为“完全类似”部分,以使您的问题更准确。

标签: shell awk


【解决方案1】:

假设您想要所有对象的所有键,并且键列在对象下方,您可以这样做:

awk '/OBJECT-TYPE/ { obj= $1 } /KEY { .* }/ { print obj, $3 }' file.txt

输出:

ABC1 XYZ1
ABC3 XYZ3

如果您只想要每个对象树中第一个对象的键,其中对象树由空行分隔,您应该尝试以下操作:

awk 'BEGIN { nl=1 } /^$/ { nl=1 }  /OBJECT-TYPE/ && nl { obj= $1; nl=0; } /KEY { .* }/ { print obj, $3 }' file.txt

输出:

ABC1 XYZ1
ABC2 XYZ3

【讨论】:

  • 感谢这个解决方案也很有帮助。我需要所有的钥匙,所以选择选项 1。
【解决方案2】:

很难说出你真正想要做什么。

awk '/OBJECT-TYPE/ {a[$1]=$1} /KEY/ { print a["ABC" substr($3,length($3))], $1; split("",a) }'

【讨论】:

    【解决方案3】:

    以下内容可能很接近。它适用于给定的输入,但它做出了我不知道是否正确的假设。例如,它假定大括号和键值之间有空格。

    #!/usr/bin/awk -f
    
    /OBJECT-TYPE/ {
      for(i=2; i<=NF; i++) {
         if( $i ~ /OBJECT-TYPE/ )
            key = $(i-1);
      }
    }
    
    /KEY +\{.*\}/ {
       for(i=1; i < NF; i++) {
          if ( $i == "KEY" ) {
             print key, $(i+2);
          }
       }
    }
    

    【讨论】:

    • 对不起,OBJECT-TYPE 和 KEY 在输入文件的不同行。在我的前几次编辑中,我没有给出块引用。
    • @ericsmith:我可能不明白,但答案仍然适用于该输入。它不依赖于他们在同一条线上。
    • @ericsmith:如果您认为这回答了您的问题,请修改您的问题,使其与答案相符。
    【解决方案4】:

    向后遍历文件可能会更容易,找到 KEY 和所有 Object-Types

    tac filename | awk '/KEY/ {key = $3} /OBJECT-TYPE/ {print $1, key}'
    

    根据您上面的示例,此输出

    ABC3 XYZ3
    ABC2 XYZ3
    ABC1 XYZ1
    

    如果您需要输出以与原始文件相同的顺序出现,请将|tac 添加到管道中。

    【讨论】:

    • 但是 ABC2 XYZ3 不应该出现在输出中。很高兴了解 tac 命令。
    • @ericsmith,您的要求并不那么明确。很高兴你找到了一些有用的东西。
    猜你喜欢
    • 2017-05-17
    • 2013-10-07
    • 2017-02-26
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-30
    相关资源
    最近更新 更多