使用 awk 提取特定列中的内容

使用 awk 提取特定列中的内容

我有 4 个字段,我想从最后一列开始并忽略前 3 列。我如何在 awk 中使用 NF 来做到这一点?

root     pts/0        192.168.108.1    Mon Mar 19 08:45   still logged in
root     tty1                          Mon Mar 19 08:45   still logged in
reboot   system boot  3.10.0-693.el7.x Mon Mar 19 08:44 - 08:49  (00:04)
root     pts/0        192.168.108.1    Sun Mar 18 13:06 - crash  (19:37)
root     tty1                          Sun Mar 18 13:06 - crash  (19:38)
reboot   system boot  3.10.0-693.el7.x Sun Mar 18 13:01 - 08:49  (19:47)
root     pts/2        192.168.108.1    Sat Mar 17 12:38 - 13:09  (00:31)
root     pts/1        192.168.108.1    Sat Mar 17 10:49 - down   (02:20)
root     pts/1        192.168.108.1    Fri Mar 16 23:17 - 00:30  (01:13)
root     pts/0        192.168.108.1    Fri Mar 16 21:25 - 12:56  (15:31)
root     tty1                          Fri Mar 16 21:25 - 13:09  (15:44)
reboot   system boot  3.10.0-693.el7.x Fri Mar 16 21:04 - 13:09  (16:05)
root     pts/2        192.168.108.1    Fri Mar 16 08:45 - crash  (12:18)
root     tty1                          Fri Mar 16 08:45 - 17:25  (08:40)
syslog                                          **Never logged in**

我只想显示:

Sun Jan 19 13:52:08 -0800 2018
**Never logged in**
Fri Mar 16 08:45 - 17:25  (08:40)
Mon Mar 19 08:45   still logged in

答案1

您可以使用一个简单的awk命令来打印最后一列内容,并使用多个空格作为字段分隔符。由于默认分隔符awk是单个空格,因此直接在最后一列上使用它会分割最后一列的内容。该NR>条件负责在应用为 定义的实际操作时跳过第一行awk

awk -F '[[:space:]][[:space:]]+' 'NR>1{print $NF}' file

或使用sed,假设列和列分隔的单词之间有多个空格仅有的在最后一栏中。

sed '1d;s/^.*  //' file

OP显然重新表述了问题,以转储last他们想要最后一列输出的列命令的输出。由于中间列本身可能有空格,因此我们对包含日期名称的列进行匹配,并从那里打印到行尾,即

last | awk ' {
     for( i=1;i<=NF;i++ ) {
         if ( $i ~ /Mon|Tue|Wed|Thu|Fri|Sat|Sun/ ) {
             j = 0
             str = ""
             for ( j=i; j<=NF;j++ ) {
                 str = ( str ? (str FS $j):$j )
             }
             print str
             break
         }
     }
 }'

答案2

对于问题的原始版本,我喜欢并投票了 Inian 的答案,并删除了这个,但现在问题已经改变了......

awk 'NR>1{if ($2~/^\*\*/) $2=foo;if ($3!~/^[[:digit:].]+$/) $3=foo; $1=$2=$3="";print}' file

if如果第二列是**Never或第三列不是 IP 地址,则语句应在第二列和第三列中放置虚拟值,但如果存在其他奇怪的可能性,则会导致答案失败......

为了便于阅读,让我们重新发布一句台词,因为它有点长......

awk 'NR > 1 {
  if ( $2 ~ /^\*\*/ ) $2=foo
  if ( $3 !~ /^[[:digit:].]+$/ ) $3=foo
  $1=$2=$3=""
  print }' file

相关内容