일치하는 문자열이 있는 줄을 인쇄하려고 하는데 다른 줄에도 "NA"를 인쇄하고 싶습니다.

일치하는 문자열이 있는 줄을 인쇄하려고 하는데 다른 줄에도 "NA"를 인쇄하고 싶습니다.

다음과 같은 파일이 있습니다.

Volume1  
created=Monday  
blah blah  
foo foo  
lock mode=exclusive  
ops  
layer id=1  

Volume2  
created=Tuesday  
jibber jabber  
foo foo  
ops  
layer id=2  

Volume3  
created=Wednesday  
blaaah  
foooo  
lock mode=shared  
ops  
layer id=3

내가 원하는 것은 "잠금 패턴"에 대한 grep이며, 패턴이 있으면 전체 줄을 인쇄하고, 그렇지 않으면 "NA"를 인쇄하고 싶습니다. 일치하지 않는 줄의 내용을 인쇄하는 방법을 알 수 없는 것 같습니다. 나는 awk나 sed도 이것을 할 수 있다고 확신합니다.

나는 다음과 같은 코드를 시도해 왔습니다.

grep -A6 Volume | grep "lock mode" <file>

이 예에서는 출력에 다음이 표시되기를 원합니다.

lock mode=exclusive  
NA  
lock mode=shared

답변1

그것은 간단합니다 perl:

perl -l -00 -ne 'print /lock mode.*/ ? $& : "NA"'
  • -l출력 필드 구분 기호를 줄 바꿈으로 설정
  • -00: 단락 모드(단락으로 기록)
  • -ne code: 각 입력 레코드에 대한 코드 실행
  • 레코드 lock mode뒤에 줄바꿈이 아닌 문자가 여러 개 오면 일치 항목( $&) 또는 NA기타 항목을 인쇄합니다.

기본적으로@iruvar의 awk 솔루션, 하지만 perl.

답변2

단락 awk모드

awk -v RS= '{match($0, /lock mode=[^\n]+/); 
  print RSTART? substr($0, RSTART, RLENGTH): "NA"}' file

이로 RS=인해 각 단락이 단일 레코드로 처리됩니다. 부르다성냥lock mode=....미리 정의된 변수 RSTARTsum 에 좌표를 입력합니다 RLENGTH. 0이 아니면 RSTART합계 RSTART와 해당 부분 문자열을 인쇄하고, 그렇지 않으면 인쇄합니다.RLENGTHNA

답변3

GNU와 함께sed

sed -n '
    /Volume/!d
    :a
    n
    /lock mode/{
        p
        d
        }
    /^\s*$/!ba
    c\NA
    ' <file>

그리고

awk '
    BEGIN{
        FS="\n"
        RS="\n\n"
    }
    /lock mode/{
        for(i=1;i<=NF;i++)
            if($i ~ /lock mode/)
                print $i
        next
    }
    {
        print "NA"
    }
    ' <file>

관련 정보