AWK - 打印最后一列以及空值

AWK - 打印最后一列以及空值

$NF如果我们不知道最后一列号,我们可以使用打印文件中每一行的最后一列。

但我面临的困难是最后一列有空值。

例如,解析who命令

$ who
root     tty1         2018-01-25 09:36
root     pts/0        2018-05-30 07:39 (192.168.1.134)
root     pts/1        2018-05-28 23:12 (192.168.1.134)
root     pts/2        2018-06-01 10:01 (192.168.1.188)

得到结果:

$ who | awk '{print $NF}'
09:36
(192.168.1.134)
(192.168.1.134)
(192.168.1.188)

预期结果

(192.168.1.134)
(192.168.1.134)
(192.168.1.188)

让我知道在一句台词中获得预期结果的可能性。

编辑1:上述场景仅是一个示例。我不喜欢更改分隔符来实现结果。

编辑2:字段少于最大值的行中没有任何内容(输出的空行)

答案1

要仅输出具有最大列数的行的最后一列,您可以执行以下操作:

who | awk '
  NF > max  {max = NF; output = ""}
  NF == max {output = output $NF ORS}
  END       {printf "%s", output}'

为每一行输入输出一行,但对于没有最大列数的行为空:

who | awk '
  NF > max {max = NF}
  {n[NR] = NF}
  NF == max {last[NR] = $NF}
  END {for (i = 1; i <= NR; i++) print n[i] == max ? last[i] : ""}'

答案2

如果您只想从具有最多字段的行中获取最后一个字段,则需要读取数据两次:一次找出最多的字段数,另一次打印字段。只读一次并不能解决问题:任何行都可能比之前有更多的字段,而且没有办法知道。

使用awk(注意文件名给出两次):

awk -vfields=0 'FNR==NR {if (NF > fields) fields=NF; next} 
     NF >= fields { print $NF } NF < fields {print ""}' file file

如果file包含

foo bar
one two three four
1 2 3
a b c d

这将打印第四个字段,或者对于没有它的行为空:



d

当然,这不适用于管道,您必须使用临时文件。

另一种解决方案是缓存要打印的字段,直到出现包含更多字段的行,如下所示史蒂芬的回答

答案3

检查第 5 个字段是否匹配\(.*\),如果匹配则打印。

who | awk '$5 ~ /\(.*\)/{print $5}'

如果您只对地址感兴趣,ip请更改正则表达式:

who |  awk '$5 ~ /\((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\)/{print $5}'

答案4

如果您只想在该列可用的情况下获取最后一列,请使用您所选择的行这一事实想要只有四列:

who | awk 'NF > 4 { print $NF }'

或者,为了获得类似的数据,

w -hi | awk '{ print $3 }'

相关内容