sed를 사용하여 일치하는 패턴 아래 줄 블록을 인쇄하는 방법

sed를 사용하여 일치하는 패턴 아래 줄 블록을 인쇄하는 방법

첫 번째 줄을 레이블로 사용하여 정기적으로 새 텍스트 블록을 추가하는 로그 파일이 있습니다. 모든 태그는 +로 시작합니다. 블록에는 종료 모드가 없습니다. 각 블록은 한 줄 또는 여러 줄이 될 수 있습니다.

+numbers
23
-87
12
+letters
b
w
a
q
+sentences
line of text
another line of text
+numbers
2
34
+address
line1
line2
line3
+numbers
4
87

주어진 태그로 시작하는 모든 블록을 인쇄하고 싶습니다. 예를 들어 +숫자에 대해 보고 싶은 내용은 다음과 같습니다.

+numbers
23
-87
12
+numbers
2
34
+numbers
4
87

또는 +주소의 경우:

+address
line1
line2
line3

awk를 사용하여 이 작업을 수행할 수 있습니다. 하지만 저는 sed 솔루션을 찾고 있습니다.

답변1

다음 중 하나를 사용하여 이 작업을 수행할 수 있습니다 sed(빈 줄, 연속 블록 등 모든 입력에 대해 작동해야 함 +numbers).

sed -e '/^+/!{H;$!d;}' -e 'x;/^+numbers/!d' logfile

작동 방식:

sed '/^+/!{         # if a line doesn't start with a + (so, not a tag)
H                   # append it to hold space and then,
$!d                 # if it's not the last line, delete it (that is, get a
}                   # new input line and restart the cycle); 
x                   # otherwise, exchange buffers and 
/^+numbers/!d'      # if the pattern space doesn't match "^+numbers", delete it
logfile

즉, "표시된" 라인은 실행 시 유지 버퍼에 저장되고, x블록의 나머지 라인은 실행 시 추가됩니다. H다음 "표시된" 줄이 패턴 공간(또는 마지막 줄)에 들어가면 버퍼가 다시 교체되므로 이제 패턴 공간에는 전체 줄 블록이 포함됩니다. 다음으로 시작하면 자동 인쇄 문제일 뿐입니다.+numbers

답변2

두 개의 GNU가 있습니다 sed.

전제 조건: 로그 파일에 빈 줄이 포함되어 있지 않습니다.

sed 's/^+/\n&/' logfile | sed -n '/+numbers/,/^$/{ /^$/d; p }'

산출:

+숫자
이십 삼
-87
12
+숫자
2
34
+숫자
4
87

바라보다man sed

답변3

tag=address
sed -n "/^+${tag}/,/^+/ {/^[^+]/p; /^+${tag}/p; }" file

이것~ 할 것이다파일에 동일한 태그가 있는 연속 블록이 포함되어 있으면 중단됩니다. 범위 끝 정규식은 다음 블록의 태그를 사용합니다.

비교해 보면, 이 경우 awk 명령은 중단되지 않습니다.

awk -v tag=address '/^\+/ {p = $0 ~ "\\+" tag "$"} p' file
awk -v tag=numbers -v RS='+' '$1 == tag {printf "+%s", $0}' file

관련 정보