여러 줄 grep을 수행하는 방법

여러 줄 grep을 수행하는 방법

두 줄에 나타나는 텍스트에 대해 grep을 어떻게 수행합니까?

예를 들어:

pbsnodesLinux 클러스터의 활용도를 반환하는 데 사용하는 명령입니다.

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_(유닉스)

답변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더 편안한 방법으로 이동할 수 있습니다.

관련 정보