如何執行多行 grep

如何執行多行 grep

如何對出現在兩行上的文字執行 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

https://en.wikipedia.org/wiki/Pipeline_(Unix)

答案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

對於可變記錄組合(例如,使用空分隔行),您可以使用分支命令tb,但awk可能會以更舒適的方式到達那裡。

相關內容