2012-09-19 47 views
1

如此远熟练制作的脚本如何使用awk挑出“第二”值?

iostat -p -x 1 2| grep $1[^[:digit:]] | awk '{print $9}' 

将返回两行:

0.16 
0.00 

因为iostat的走的是两条样品。但你已经知道了。我的问题是,既然你和我都知道每次都会有两行,我怎么挑出第二个呢?

+0

什么跟读者奉承的?直截了当的问题通常更易于阅读。 – nneonneo

回答

6

{print $9}之前添加NR==2告诉awk到2

例如,赛会记录我的系统上,

$ iostat -x /dev/sda 1 2 | grep sda 

$ iostat -x /dev/sda 1 2 | grep sda | awk 'NR==1 {print $9}' 

$ iostat -x /dev/sda 1 2 | grep sda | awk 'NR==2 {print $9}' 

生产

sda    0.11  1.04 2.00 1.28 125.95 63.24 115.15  0.07 21.04 4.66 46.60 2.36 0.78 
sda    0.00  0.00 0.00 0.00  0.00  0.00  0.00  0.00 0.00 0.00 0.00 0.00 0.00 
0.07 
0.00 

这里是 “0.00” 线是第三个命令的结果。

附加说明:不需要单独运行grep命令,因为awk可以匹配文本。但是,awk脚本则需要一个索引变量。下面的第一个例子是一个简单的grep来显示awk的工作原理。接下来的两个例子是直接的awk代码,它有一个匹配测试来增加一个索引,另一个匹配测试加上索引测试来打印。最后一个例子展示了如何摆脱匹配表达式的额外外观。请注意,在这些示例中,为了清晰起见,我将print $9替换为print,而将$1[^[:digit:]]替换为sda[^0-9]。下面是该做awk,而不是匹配在grep例子:

$ iostat -p -x 1 2 | grep 'sda ' 
sda    0.11  1.04 2.00 1.28 125.70 63.16 115.09  0.07 21.04 4.66 46.57 2.36 0.78 
sda    0.00  0.00 0.00 0.00  0.00  0.00  0.00  0.00 0.00 0.00 0.00 0.00 0.00 

$ iostat -p -x 1 2 | awk '/sda[^0-9]/ {++t} t==1 && /sda[^0-9]/ {print}' 
sda    0.11  1.04 2.00 1.28 125.70 63.16 115.09  0.07 21.04 4.66 46.57 2.36 0.78 

$ iostat -p -x 1 2 | awk '/sda[^0-9]/ {++t} t==2 && /sda[^0-9]/ {print}' 
sda    0.00  0.00 0.00 0.00  0.00  0.00  0.00  0.00 0.00 0.00 0.00 0.00 0.00 

$ iostat -p -x 1 4 | awk '/sda[^0-9]/ && t++ && t==2 {print}' 
sda    0.00  0.00 0.00 0.00  0.00  0.00  0.00  0.00 0.00 0.00 0.00 0.00 0.00 
+0

按照我的系统上的预期工作,但好像它将打印所有内容而不是一个字段? – mvd

+0

在我的回答中,前两行输出来自'iostat -x/dev/sda 1 2 | grep sda',即不跟awk。其他两行输出显示NR == 1或NR == 2的结果。 (注意,我编辑的答案是使用sda而不是sdf,并且在一分钟内会对此添加评论。) –

+0

@Mikhail,我添加了关于如何在awk中执行grep的注释。对于这个应用程序来说,在awk中而不是在grep中匹配这些行并没有什么帮助,但在其他情况下,它会更灵活或更通用。 –

2

管它到tail -1,这将选择最后一行。

iostat -p -x 1 2| grep $1[^[:digit:]] | awk '{print $9}' | tail -1 
2

结合headtail让您从输入选择线的任何序列:

(cmd) | tail -n+2 | head -n 1 

获取输入的第二行不管命令的输出有多长。