在单个命令中使用两个分隔符从 awk 获取结果

Cru*_*se5 3 awk shell-script

仅 ping 命令的输出:

[root@servera ~]# ping -c 4 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=128 time=8.04 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=128 time=7.47 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=128 time=7.72 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=128 time=7.50 ms

--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3007ms
rtt min/avg/max/mdev = 7.473/7.683/8.037/0.225 ms
Run Code Online (Sandbox Code Playgroud)

我只想从“4 returned”中捕获整数4。

ping -c 4 8.8.8.8 | awk -F ',' '/received/ { print $2 }'

结果是 4 received。我只想捕获上述命令中的数字 4。我怎样才能做到这一点?现在分隔符是空格。

Ed *_*ton 10

所有你需要的是:

awk '/received/{print $4}'
Run Code Online (Sandbox Code Playgroud)

例如,用于cat file获取与awk问题中相同的输入:

$ cat file
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=128 time=8.04 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=128 time=7.47 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=128 time=7.72 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=128 time=7.50 ms

--- 8.8.8.8 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3007ms
rtt min/avg/max/mdev = 7.473/7.683/8.037/0.225 ms
Run Code Online (Sandbox Code Playgroud)

$ cat file | awk '/received/{print $4}'
4
Run Code Online (Sandbox Code Playgroud)

显然只需替换cat fileping -c 4 8.8.8.8您的实际测试即可。

回应下面的 OP 评论,询问它匹配哪一行:

$ awk '/received/' file
4 packets transmitted, 4 received, 0% packet loss, time 3007ms
Run Code Online (Sandbox Code Playgroud)

以及为什么要打印字段 4:

$ awk '/received/{for (i=1; i<=NF; i++) print i, "<" $i ">"}' file
1 <4>
2 <packets>
3 <transmitted,>
4 <4>
5 <received,>
6 <0%>
7 <packet>
8 <loss,>
9 <time>
10 <3007ms>
Run Code Online (Sandbox Code Playgroud)


ter*_*don 7

您已经得到了一些很好的 awk 答案,所以这里有一些替代方案。

  1. GNUgrep

    $ ping -c 4 8.8.8.8 | grep -oP '\d+(?= received,)'
    4
    
    Run Code Online (Sandbox Code Playgroud)
  2. 珀尔

    $ ping -c 4 8.8.8.8 | perl -lne 'print $1 if /(\d+) received,/'
    4
    
    Run Code Online (Sandbox Code Playgroud)
  3. sed

    $ ping -c 4 8.8.8.8 | sed -En 's/.*, ([0-9]+) received,.*/\1/p'
    4
    
    Run Code Online (Sandbox Code Playgroud)


Rom*_*nov 7

还有另一种方法可以做到这一点awk(类似于对其中一个答案进行评论)

awk -F, '/received/ {print int($2)}'
Run Code Online (Sandbox Code Playgroud)

函数int()将“丢弃”第一个数字之后的非数字信息

  • 或者 `$2+0` 也应该有效,无论如何+1 (5认同)

jes*_*e_b 6

字段分隔符可以是正则表达式,因此您可以在 awk 中设置多个字段分隔符,[ ]例如:

awk -F '[, ]' '/received/ {print $5}'
Run Code Online (Sandbox Code Playgroud)

然而在这种情况下,我可能会删除收到的单词:

 awk -F, '/received/ {sub(/received/, "", $2); print $2}'
Run Code Online (Sandbox Code Playgroud)

awk sub() 函数sub(regexp, replacement [, target])将查找正则表达式表示的模式,将其替换为replacement,并且可以选择缩小到目标列。

  • 我想知道如果你只是强制字段的数字转换,即 `awk -F, '/received/ {print $2+0}'` ,是否会激怒 awk 诸神? (3认同)