나는 awk가 라인 블록의 시작 부분으로 이동하여 블록의 맨 아래에 도달한 후 다시 처리를 시작하고 마지막 라인을 처리하길 원합니다.
기본적으로 텍스트 블록이
<START of block>
Hi
How
Are
You
<END of block>
"You"가 블록의 마지막 줄인지 확인하고 블록을 인쇄하고 그렇지 않으면 인쇄하지 않기를 원합니다. 내 파일에 서로 다른 값을 가진 여러 개의 텍스트 블록이 있습니다.
처리를 시작하기 위해 "line" 변수에 저장된 특정 라인으로 이동하도록 awk를 얻을 수 있다면 내 목적은 해결될 것입니다.
답변1
만약에나는 올바르게 이해합니다: - 귀하의 입력에는 " "에 대한 전용 줄이 있고 <START of block>
" "에 대한 또 다른 줄이 있으며 "You "end" " <END of block>
로 시작하는 경우 블록을 인쇄하려고 합니다(두 토큰을 모두 포함합니까? 아니면 포함하지 않습니까?) .<END of block>
그 다음에:
awk -v regstart="<START of block>" -v regend="<END of block>" -v reglast="You" '
BEGIN { rem="we will remember a block between those regstart and regend markers, and only print it if the last line matches reglast"
remember=0; rem="by default we are not inside a block, so we do not remember lines until we match the regstart"
}
( $0 ~ regstart ) {
remember=1; nb=0;
}
( remember==1 ) {
line[++nb]=$0 ;
}
( $0 ~ regend ) {
remember=0; rem="we reached the end of block, we do not remember anymore the lines we see until next regstart"
if ( line[(nb-1)] ~ reglast ) {
## for(i=2;i<=(nb-1);i++) { rem="this version do NOT show the 2 marker lines"
for(i=1;i<=nb;i++) { rem="this version shows the 2 marker lines"
print line[i]
}
## print "" ; rem="uncomment this line if you want a separator lines between blocks"
}
}
'
참고 1: 시작, 끝 및 마지막 줄을 일치시키기 위해 정규식을 사용했지만 "=="를 사용하여 정확한 문자열을 비교할 수 있습니다.
참고 2: 인쇄 부분: 2에서 nb-1로 이동하여 START(라인 [1]에 저장됨) 및 END(라인 [nb]에 저장됨) 라인을 표시하지 않을 수 있습니다.
참고 3: 위 스크립트는 각 블록을 원활하게 처리하고 "reglast"와 일치하는 줄로 끝나는 블록만 인쇄합니다. 즉, 하나만 인쇄하는 것이 아니라 일치하는 모든 블록을 인쇄합니다.
답변2
awk
다음은 더 짧은 입력 대안입니다.
< infile awk -v RS='\n<END of block>' '$NF == "You" { print $0 RS }'
<START of block>
Hi
How
Are
You
<END of block>
<START of block>
thank
You
<END of block>
$NF
여기서(정적 문자열(레코드 구분 기호) 설정의 정의에 따라 RS
이를 기준으로 각 블록을 구분하도록)는 마지막 행의 값을 나타내므로 Yes
문자열과 같으면 블록을 인쇄하고 다시 복원합니다. RS도요.
입력 파일:
<START of block>
Hi
How
Are
You
<END of block>
<START of block>
Hi
How
Are
not YOU
<END of block>
<START of block>
thank
You
<END of block>
<START of block>
welcome
to
Unix
<END of block>