【问题标题】:Printing the last column of a line in a file打印文件中一行的最后一列
【发布时间】:2012-10-14 07:31:00
【问题描述】:

我有一个不断被写入/更新的文件。我想找到包含特定单词的最后一行,然后打印该行的最后一列。

文件看起来像这样。随着时间的推移,更多的 A1/B1/C1 行将被附加到它上面。

A1 123 456
B1 234 567
C1 345 678
A1 098 766
B1 987 6545
C1 876 5434

我尝试使用

tail -f file | grep A1 | awk '{print $NF}'

打印值 766,但没有输出。

有没有办法做到这一点?

【问题讨论】:

    标签: file awk tail


    【解决方案1】:

    由于缓冲,您什么都看不到。当有足够的行数或到达文件末尾时,将显示输出。 tail -f 表示等待更多输入,但file 中没有更多行,因此到grep 的管道永远不会关闭。

    如果您从 tail 中省略 -f,则会立即显示输出:

    tail file | grep A1 | awk '{print $NF}'
    

    @EdMorton 当然是对的。 Awk 也可以搜索A1,这将命令行缩短为

    tail file | awk '/A1/ {print $NF}'
    

    或不带尾,显示所有包含A1的行的最后一列

    awk '/A1/ {print $NF}' file
    

    感谢@MitchellTracy 的评论,tail 可能会错过包含A1 的记录,因此您根本没有得到任何输出。这可以通过切换tailawk来解决,先搜索文件,然后才显示最后一行:

    awk '/A1/ {print $NF}' file | tail -n1
    

    【讨论】:

    • 你永远不需要 grep+awk 因为 awk 可以做它自己的 RE 比较。 “grep A1 | awk '{print $NF}'”应该只是“awk '/A1/{print $NF}'”。另外,如果你不使用tail -f,那么你根本不需要tail,你可以这样做: awk '/A1/{f=$NF} END{print f}' file
    • 这不太正确,因为该列可能不会出现在原始tail 为您提供的窗口中。除非你知道它会以一定的频率出现,否则awk '/A1/ {print $NF}' file | tail -n1 会更安全。
    【解决方案2】:

    要打印一行的最后一列,只需使用 $(NF):

    awk '{print $(NF)}' 
    

    【讨论】:

    • 为什么不只是$NF
    【解决方案3】:

    一种使用awk的方式:

    tail -f file.txt | awk '/A1/ { print $NF }'
    

    【讨论】:

    • 我认为这是已发布问题的正确解决方案(+1!)但现在我明白我不明白这个问题。 OP 想要文件最后一行的最后一个字段,但如果您使用 tail -f,则没有最后一行。也许他的意思是文件中当前的最后一行,在这种情况下,请参阅我的其他 cmets 之一。
    • 非常好和简单。竖起大拇指。不赞成awk 的神秘语法:)
    【解决方案4】:

    你可以在没有 awk 的情况下使用一些管道来做到这一点。

    tac file | grep -m1 A1 | rev | cut -d' ' -f1 | rev
    

    【讨论】:

    • 这解决了你的问题,但它并没有真正使用awk。无论如何,希望它对你来说已经足够好了。
    【解决方案5】:

    也许这行得通?

    grep A1 file | tail -1 | awk '{print $NF}'
    

    【讨论】:

      【解决方案6】:

      您可以在awk 中完成所有操作:

      <file awk '$1 ~ /A1/ {m=$NF} END {print m}'
      

      【讨论】:

      • 您不需要 split() 和数组,只需保存最后一个字段并打印:awk '/A1/{f=$NF} END{print f}' file
      【解决方案7】:

      使用 Perl

      $ cat rayne.txt
      A1 123 456
      B1 234 567
      C1 345 678
      A1 098 766
      B1 987 6545
      C1 876 5434
      
      
      $ perl -lane ' /A1/ and $x=$F[2] ; END { print "$x" } ' rayne.txt
      766
      
      $
      

      【讨论】:

      • 看起来太复杂了,就做perl -lane 'print $F[2] if /A1/' rayne.txt
      • @Hi-Angel ..问题要求最后一次出现 A1。您的答案将打印所有匹配项。顺便说一句,如果您喜欢我的答案,请点赞
      【解决方案8】:

      awk -F " " '($1=="A1") {print $NF}' FILE | tail -n 1

      使用 awk 并将字段分隔符 -F 设置为空格“”。

      使用 pattern $1=="A1"action {print $NF},这将打印第一个字段为“A1”的每条记录中的最后一个字段。将结果通过管道传输到尾部并使用-n 1 选项仅显示最后一行。

      【讨论】:

        【解决方案9】:

        这里不是实际问题,但可能对某些人有所帮助:我正在做awk "{print $NF}",请注意错误的引号。应该是awk '{print $NF}',这样shell就不会扩展$NF

        【讨论】:

          【解决方案10】:

          在文件上执行:

          awk 'ORS=NR%3?" ":"\n"' filename
          

          你会得到你想要的。

          【讨论】:

            【解决方案11】:

            ls -l | awk '{print $9}' | tail -n1

            【讨论】:

            • 这与 OP 的问题有什么关系?
            猜你喜欢
            • 2022-06-15
            • 2016-01-19
            • 1970-01-01
            • 2014-03-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2023-03-28
            相关资源
            最近更新 更多