일치하는 문자열이 있는 줄을 인쇄하려고 하는데 다른 줄에도 "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=....사전 정의된 변수 RSTART및 에 채웁니다 RLENGTH. RSTART가 0이 아닌 경우 RSTART및 에 해당하는 부분 문자열이 RLENGTH인쇄되고, 그렇지 않으면 NA인쇄됩니다.

답변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>

관련 정보