如何执行多行grep

spu*_*der 15 grep sed awk text-processing

您将如何对出现在两行上的文本执行 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
Run Code Online (Sandbox Code Playgroud)

我想确定与处于“空闲”状态的节点匹配的进程数。到目前为止,我已经能够确定“进程数”和“处于空闲状态的节点”,但我想将它们组合成一个显示所有空闲进程的命令。

在上面的例子中,正确答案是 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
Run Code Online (Sandbox Code Playgroud)

如何搜索读取为“procs = x”的每一行,但前提是它上面的行读取为“state = free”?

Sté*_*las 12

如果数据始终采用这种格式,您可以简单地编写它:

awk -vRS= '$4 == "free" {n+=$7}; END {print n}'
Run Code Online (Sandbox Code Playgroud)

RS=意味着记录是段落)。

或者:

awk -vRS= '/state *= *free/ && match($0, "procs *=") {
  n += substr($0,RSTART+RLENGTH)}; END {print n}'
Run Code Online (Sandbox Code Playgroud)


小智 5

$ 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
Run Code Online (Sandbox Code Playgroud)

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


bin*_*lse 3

GNU 实现grep带有两个参数,用于打印匹配之前 ( -B) 和之后 ( -A) 的行。手册页的片段:

   -A NUM, --after-context=NUM
          Print NUM lines of trailing context after matching lines.  Places a line containing  a  group  separator  (--)  between  contiguous  groups  of  matches.   With  the  -o  or
          --only-matching option, this has no effect and a warning is given.

   -B NUM, --before-context=NUM
          Print  NUM  lines  of  leading  context  before  matching  lines.   Places  a  line  containing  a group separator (--) between contiguous groups of matches.  With the -o or
          --only-matching option, this has no effect and a warning is given.
Run Code Online (Sandbox Code Playgroud)

因此,在您的情况下,您必须 grepstate = free并打印以下行。将其与问题中的片段相结合,您将得到类似的结果:

usr@srv % pbsnodes | grep -A 1 'state = free' | grep "procs = " | awk  '{ print $3 }' | awk '{ sum+=$1 } END { print sum }'
6
Run Code Online (Sandbox Code Playgroud)

更短一点:

usr@srv % pbsnodes | grep -A 1 'state = free' | awk '{ sum+=$3 } END { print sum }'
6
Run Code Online (Sandbox Code Playgroud)