【问题标题】:Grep for one thing then cut from the line belowGrep 一件事然后从下面的行中删除
【发布时间】:2012-07-20 15:08:42
【问题描述】:

好吧,我想不通。就像我使用 grep 来获取某些信息的文件一样,它的设置是这样的。

#aaaa
<numbers 123456>

blah
blah
blah

#bbbb
<numbers 2156488>

blah
blah
blah

#cccc
<numbers 5478624>

blah
blah
blah

我正在做的是寻找aaaabbbbcccc,而我真正需要的信息是数字。就像当我 grep for aaaa 一样,我想要获得的东西实际上只是它下面的数字。在这种情况下,它将123456

我知道如何用 grep 查找 aaaa,但我不知道如何转到下一行并删号。

【问题讨论】:

    标签: linux bash shell scripting grep


    【解决方案1】:

    使用 sed:

    sed -n '/aaaa/{
    N
    s/[^0-9]*\([0-9]*\).*/\1/p
    }' input_file
    

    【讨论】:

      【解决方案2】:

      您可以使用grep-C 选项来显示一行上下文。然后你可以在最后一行tail (-n 1),cut 使用空格并选择第二个字段,cut 再次使用&gt; 并选择第一个字段。因此:

      $ grep aaaa file -C 1 | tail -n 1 | cut -f2 -d' ' | cut -d'>' -f1
      123456
      

      将返回您请求的号码。

      最重要的部分是grep-C选项

      【讨论】:

      • 这是一个 GNU grep 扩展。由于这被标记为 Linux,这是公平的,但它不会在任何地方都有效。
      • 您也可以在匹配后的 1 行而不是前后使用 -A 1 选项。
      • 是的,但仍然需要tail,因为匹配线仍会显示。因此,命令长度没有更新。至于这是一个 GNU 扩展,我承认我不知道。由于我不知道其他greps,如果提问者告诉我这不是他需要的,我会保留答案并删除它:)
      【解决方案3】:

      在我看来,这更像是 sed 的工作:

      sed -n '/^#[a-z]\{4\}/{ N; s/#.*\n<numbers //; s/>//p; }'
      

      -n 表示默认情况下不打印。 /^#[a-z]\{4\}/ 查找类似 @​​987654325@ 的行; { ... } 中的操作仅适用于此类行。 N 表示“阅读下一行”;第一个s///去掉数字前的材料;第二个删除尾随 &gt; 并打印。

      关于如何执行“删除无关材料”还有其他选项,例如只有一个替代命令:s/[^0-9]*\([0-9][0-9]+\).*/\1/;这将捕获第一个数字字符串并删除其他所有内容。它将比最初显示的更受约束的正则表达式处理更多的输入变化。

      样本数据的输出:

      123456
      2156488
      5478624
      

      这不会自动成为sed 的工作;更改它,以便有趣的信息是比赛后的第三行,并且它会在sed 中变得繁琐(尽管N;N;N; 可能会做想要的事情)。

      【讨论】:

      • 这也可以通过awk 来完成,或者sed 是一种更快/更清洁的方式吗?
      • 可以通过awk 使用getline 函数在找到标记行时读取下一行来完成。
      【解决方案4】:

      @拉尔斯·科特霍夫

      您使用-A 1 选项的建议非常有效!

      使用您输入的答案是这样的:

      grep "aaaa" file -A 1 | grep "<numbers" | cut -d" " -f2 | cut -d">" -f1
      

      我很想把这个归功于你!

      【讨论】:

        【解决方案5】:

        如果你不坚持grep
        +0去掉">"

        awk 'f{print $2+0; exit} /^#aaaa/{f=1}' foo.txt
        

        或者

        awk 'f{print $2+0; f=0} /^#aaaa/{f=1}' foo.txt
        

        【讨论】:

          【解决方案6】:

          试试这个:

          for i in "aaaa bbbb"
          do
          sed -n '/'"$i"'/,+1 p' test |tail -n1|cut -d' ' -f2| sed 's/.$//'
          done
          

          它不是很有效,但做得很好。

          【讨论】:

            猜你喜欢
            • 2015-02-13
            • 2015-04-23
            • 1970-01-01
            • 2012-12-01
            • 1970-01-01
            • 1970-01-01
            • 2012-07-23
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多