다음과 같은 파일이 있습니다
FHEAD
THEAD
TCUST
TITEM
TTEND
TTAIL
THEAD
TCUST
TCUST
TITEM
TITEM
TTEND
TTAIL
THEAD
TCUST
TITEM
TTEND
TTAIL
THEAD
TCUST
TCUST
TITEM
TTEND
TTAIL
THEAD와 TTAIL 사이에 여러 번 나타나는 ONLY TCUST 레코드의 발생 횟수를 계산하고 해당 파일 이름과 줄을 인쇄해야 합니다.
파일이 여러 개 있으므로 파일 이름도 인쇄해야 합니다.
예상되는 결과는
THEAD TCUST TCUST TITEM TITEM TITEM TTEND TTAIL THEAD TCUST TCUST TITEM TTEND TTAIL 파일 이름
답변1
$ awk '
/THEAD/{f=1; c=0; a = $0; next}
f{a = a ORS $0; if(/TCUST/) c++}
/TTAIL/{f=0; if(c > 1){print a; m=1} }
ENDFILE{if(m) print FILENAME; m=0}
' ip.txt
THEAD
TCUST
TCUST
TITEM
TITEM
TTEND
TTAIL
THEAD
TCUST
TCUST
TITEM
TTEND
TTAIL
ip.txt
/THEAD/{f=1; c=0; a = $0; next}
모드를 시작하고, 플래그를 설정하고, 카운터를 초기화합니다. 나중에 인쇄하기 위해 현재 줄을 저장합니다.f{a = a ORS $0; if(/TCUST/) c++}
플래그를 설정한 후 입력 라인을a
변수에 누적하고 라인이 일치하면 카운터를 증가시킵니다.TCUST
/TTAIL/{f=0; if(c > 1){print a; m=1} }
종료 모드, 명확한 표시.a
counter가 다음보다 크면 내용을 인쇄1
하고m
적어도 하나의 일치 항목이 발견된 변수를 설정합니다.ENDFILE{if(m) print FILENAME; m=0}
파일의 모든 줄이 처리된 후 입력 파일 이름(m
설정된 경우)을 인쇄하고 다음 파일을 처리하기 전에 지웁니다(여러 파일 요구 사항을 지적한 @Costas에게 감사드립니다)
노트: ENDFILE
구체적 GNU awk
이고 어떻게 처리해야 할지 모르겠어요ENDFILE
GNU가 아닌 특정 솔루션에 대해 @Costas에게 감사드립니다 ENDFILE
.
$ awk '
FNR==1{if(m) print fname; m=0; fname=FILENAME}
/THEAD/{f=1; c=0; a = $0; next}
f{a = a ORS $0; if(/TCUST/) c++}
/TTAIL/{f=0; if(c > 1){print a; m=1} }
END{if(m) print fname}
' *.txt
답변2
GNU sed를 사용하면 다음과 같이 작업을 수행할 수 있습니다.
sed -sn '
/THEAD/{:1;N;/TTAIL/! b1} #collect lines from `THEAD' to `TTAIL'
/TCUST.*TCUST/{p;h} #print if there are two TCUST and set hold
${x;//F} #check hold and output if two TCUST was in it
' file1 file2 …