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