【问题标题】:How to print last two columns using awk如何使用 awk 打印最后两列
【发布时间】:2011-05-17 08:04:45
【问题描述】:

我只想打印最后两列。

【问题讨论】:

  • 不太清楚为什么它有 87 个赞成票,至少可以通过一个例子来改进它。
  • 可能是因为这个问题本质上非常简单,没有示例也很容易理解,这种情况很少见,但在这种情况下它似乎有效。我认为这里的问题不在于缺乏信息,而更多的是它表明缺乏独立研究。
  • 这个问题也是this问题的重复。
  • 这能回答你的问题吗? Print second last column/field in awk

标签: awk


【解决方案1】:

请尝试这样做以考虑所有可能的情况:

awk '{print $(NF-1)"\t"$NF}'  file

awk 'BEGIN{OFS="\t"}' file

awk '{print $(NF-1), $NF} {print $(NF-1), $NF}' file

【讨论】:

    【解决方案2】:

    试试这个

    $ cat /tmp/topfs.txt
    /dev/sda2      xfs        32G   10G   22G  32% /
    
    awk print last column
    $ cat /tmp/topfs.txt | awk '{print $NF}'
    
    awk print before last column
    $ cat /tmp/topfs.txt | awk '{print $(NF-1)}'
    32%
    
    awk - print last two columns
    $ cat /tmp/topfs.txt | awk '{print $(NF-1), $NF}'
    32% /
    

    【讨论】:

      【解决方案3】:

      使用 gawk 会出现问题:

       gawk '{ print $NF-1, $NF}' filename
      1 2
      2 3
      -1 one
      -1 three
      # cat filename
      1 2
      2 3
      one
      one two three
      

      我只是在 Solaris 10 M4000 上安装了 gawk: 因此,gawk 是 $NF-1 与 $(NF-1) 问题上的焦点。下一个问题 POSIX 说什么? 每:

      http://www.opengroup.org/onlinepubs/009695399/utilities/awk.html
      

      没有一种方向或另一种方向。不好。 gawk 表示减法,其他 awk 表示字段编号或减法。嗯。

      【讨论】:

      • 示例输入文件的前 2 行没有帮助,因为它们产生具有 either 行为的相同输出。您能否再次确认 Solaris awk 在这种情况下的行为确实不像 gawk?
      • 关于 awk 规范的链接:使用 $(NF-1) 的轶事参数是规范中计算字段索引的两个示例都使用该形式:$(NF-1)$(NF+2) .然后是“awk 中的表达式”部分,其中列出了$expr 的优先级高于expr - expr。因为NF 本身就是一个表达式,所以$NF-1 的计算结果应该是($NF)-1。毕竟,即使确实有 awk 实现将$NF-1 评估为$(NF-1),这里学到的教训是使用$(NF-1) 是安全且可移植的选择。
      【解决方案4】:

      @jim mcnamara:尝试在NF 周围使用括号,即。 e. $(NF-1)$(NF) 而不是 $NF-1$NF(适用于 Mac OS X 10.6.8 for FreeBSD awkand gawk)。

      echo '
      1 2
      2 3
      one
      one two three
      ' | gawk '{if (NF >= 2) print $(NF-1), $(NF);}'
      
      # output:
      # 1 2
      # 2 3
      # two three
      

      【讨论】:

      • 我们之前已经考虑过()。我以为我们正在讨论原始的旧 awk 行为的来源。
      • +1 表示明确的$(NF-1) 答案——至少比$NF-1 更便携;它肯定不那么模棱两可。不过,$(NF) 有点矫枉过正——只需$NF 就可以了。防范少于 2 列的行也是值得的,因为对于单列行,您将获得第一列值 两次,而对于零列(即空行),awk 命令将由于尝试访问索引为 -1 的字段而完全失败。
      • 我认为我们可以让它更短一点:gawk 'NF>=2 {print $(NF-1), $NF}'
      【解决方案5】:

      您可以使用变量NF,它设置为输入记录中的字段总数:

      awk '{print $(NF-1),"\t",$NF}' file
      

      这假设您至少有 2 个字段。

      【讨论】:

      • 你需要一个逗号 - 因为我们今天很挑剔:空格连接字段,逗号分隔打印语句中的字段。这将合并两个字段
      • 现在您正在打印“field-OFS-tab-OFS-field”。应该是awk '{print $(NF-1) "\t" $NF}' fileawk '{print $(NF-1), $NF}' fileawk 'BEGIN{OFS="\t"} {print $(NF-1), $NF}' file
      • 只是添加到前面的评论,使用'{print $x,"\t",$y}' 的问题是awk 将每个逗号分隔的变量解释为它自己的字段,所以结果实际上是field1<space><tab><space>field2,(因为它会默认情况下使用空格分隔符)而不是field1<tab>field2,这可能是您所期望的。使用输出字段分隔符 (OFS) 几乎总是您想要的。
      【解决方案6】:
      awk '{print $NF-1, $NF}'  inputfile
      

      注意:这仅在至少存在两列时才有效。在只有一列的记录上,你会得到一个虚假的"-1 column1"

      【讨论】:

      • 试试看。它确实适用于 Solaris 9 awk 和 nawk。另一种选择是 $(NF-1)
      • @coaddict - 我猜你没有使用不同的 awk 实现。旧的 awks 行为已经(可能是错误地)被提出来。我没有 gawk 来测试——这可能是你所引用的。所以我不确定你的评论为什么会被放弃。开箱即用的 Linux awk 通常是 gawk。我会测试并回帖。同时尝试 Soalris 或 HPUX 或 DGX 或其他任何东西,看看我所说的旧 awk 是什么意思。
      • 您可能因为尝试了echo 1 2 3 | awk ... 而误以为它有效。 $NF-1 在每个 awk 实现中都是 ($NF) - 1
      • “一个真正的 awk”源代码在 yacc 语法中有 40 多个冲突,考虑到 A 在 awk 中的含义,这具有讽刺意味。不同版本的 awk 解析事物的方式不同?大惊喜!
      • @THESorcerer,尝试使用echo '5 4 3 2 1' | awk '{print $NF-1,$NF; print $(NF-1), $NF}' -- 或任何其他倒数第二个字段不小于最后一个字段的输入。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-24
      • 1970-01-01
      • 2020-05-25
      • 2011-02-27
      • 2023-03-12
      • 1970-01-01
      相关资源
      最近更新 更多