如何对出现在两行上的文本执行 grep ?
例如:
pbsnodes
是我使用的命令,它返回 Linux 集群的利用率
root$ pbsnodes
node1
state = free
procs = 2
bar = foobar
node2
state = free
procs = 4
bar = foobar
node3
state = busy
procs = 8
bar = foobar
我想确定与处于“空闲”状态的节点匹配的进程数量。到目前为止,我已经能够确定“进程数量”和“处于空闲状态的节点”,但我想将它们组合成一个显示所有空闲进程的命令。
在上面的示例中,正确答案是 6 (2+4)。
我拥有的
root$ NUMBEROFNODES=`pbsnodes|grep 'state = free'|wc -l`
root$ echo $NUMBEROFNODES
2
root$ NUMBEROFPROCS=`pbsnodes |grep "procs = "|awk '{ print $3 }' | awk '{ sum+=$1 } END { print sum }'`
root$ echo $NUMBEROFPROCS
14
如何搜索每一行“procs = x”,但前提是上面的行显示“state = free”?
答案1
如果数据始终采用该格式,您可以简单地编写它:
awk -vRS= '$4 == "free" {n+=$7}; END {print n}'
(RS=
方法记录是段落)。
或者:
awk -vRS= '/state *= *free/ && match($0, "procs *=") {
n += substr($0,RSTART+RLENGTH)}; END {print n}'
答案2
$ pbsnodes
node1
state = free
procs = 2
bar = foobar
node2
state = free
procs = 4
bar = foobar
node3
state = busy
procs = 8
bar = foobar
$ pbsnodes | grep -A 1 free
state = free
procs = 2
--
state = free
procs = 4
$ pbsnodes | grep -A 1 free | grep procs | awk '{print $3}'
2
4
$ pbsnodes | grep -A 1 free | grep procs | awk '{print $3}' | paste -sd+
2+4
$ pbsnodes | grep -A 1 free | grep procs | awk '{print $3}' | paste -sd+ | bc
6
答案3
这是使用 来完成此操作的一种方法pcregrep
。
$ pbsnodes | pcregrep -Mo 'state = free\n\s*procs = \K\d+'
2
4
例子
$ pbsnodes | \
pcregrep -Mo 'state = free\n\s*procs = \K\d+' | \
awk '{ sum+=$1 }; END { print sum }'
6
答案4
如果您有固定长度的数据(固定长度指的是记录中的行数),则sed
可以使用N
命令(多次),它将下一行连接到模式空间:
sed -n '/^node/{N;N;N;s/\n */;/g;p;}'
应该给你类似的输出:
node1;state = free;procs = 2;bar = foobar
node2;state = free;procs = 4;bar = foobar
node3;state = busy;procs = 8;bar = foobar
对于可变记录组合(例如,使用空分隔行),您可以使用分支命令t
和b
,但awk
可能会以更舒适的方式到达那里。