다음은 텍스트입니다.
* Tue This is the first line
– info 1
– info 2
– info 3
* Wed This is not to be included
이 텍스트의 출력은 다음과 같아야 합니다.
* Tue This is the first line
– info 1
– info 2
– info 3
참고: awk 및 sed를 시도했지만 출력을 얻지 못했습니다. 문제는 START와 END가 동일한 "*"(별표)이고 첫 번째 항목이 출력에 포함되어야 한다는 것입니다.
답변1
나는 이것을 올바르게 이해하기를 바랍니다. 이 스크립트는 두 번째 줄부터 버퍼 끝까지 *
모든 것을 제거하여 예제에서 원하는 출력을 생성합니다.
sed -n 'H;1h;$x;$s/\(\*[^*]*\)\n\*.*$/\1/p'
설명 H
보유 버퍼에 모든 라인( )을 추가합니다. 마지막 라인에서는 홀드 버퍼와 패턴 버퍼( $x
)를 교체하여 전체 파일을 하나의 패턴으로 갖게 됩니다. 이 모드에서는 유지될 부분이 설정 \(\)
및 유지되며( \1
), 개행 안의 모든 내용은 *
제거됩니다.
이는 설명에 적합하지만 가능한 모든 예에 맞지 않으면 스크립트를 수정할 수 있습니다.
답변2
perl -lne 'if ( m?^\*? ... m?^\*? ) { print if !// || !$a++ }'
sed -e '
/^\*/!d
:loop
$q; N
/\n\*/!bloop
s/\(.*\)\n.*/\1/;q
'
sed -e '
/^\*/!d
:loop
n
//!bloop
Q
'
답변3
샘플 텍스트를 변수에 저장합니다.
$ SAMPLE=$(cat <<EOF
* Tue This is the first line
– info 1
– info 2
– info 3
* Wed This is not to be included
* Tue This is the first line
– info 1
– info 2
– info 3
* Wed This is not to be included
EOF
)
처리 awk
방법 $SAMPLE
:
$ awk '{if($1~"\*"){if(p==1){p=0;next}else{p=1}}if(p==1){print $0}}' <<<"$SAMPLE"
* Tue This is the first line
– info 1
– info 2
– info 3
* Tue This is the first line
– info 1
– info 2
– info 3
편집하다
의견에서 제안한 것처럼 놀랍도록 우아한 awk
솔루션이 있습니다.
$ awk '/^\*/{p=!p};p' <<<"$SAMPLE"
* Tue This is the first line
– info 1
– info 2
– info 3
* Tue This is the first line
– info 1
– info 2
– info 3
작동 방식:
/^\*/{p=!p};
p
- 의 값이 바뀌게 됩니다1
. 정규식을 처음 발견하면0
가 됩니다. 두 번째로 발견되면 그렇게 됩니다.1
/^\*/
p
0
p
- 이는 와 동일합니다p{print}
. 는 의 기본 작업이므로print
전제 조건이 해당 값으로 평가될 때(이 경우 가 될 때 )awk
항상 인쇄됩니다 .true
p
1