파일의 텍스트는 다음과 같습니다.
Pseudo name=Apple
Code=42B
state=fault
Pseudo name=Prance
Code=43B
state=good
"42B"를 grep하고 위의 텍스트에서 출력을 가져와야 합니다. 예를 들면 다음과 같습니다.
Pseudo name=Apple
Code=42B
state=fault
이것을 grep
달성하기 위해 //를 사용하는 방법을 아는 사람이 있습니까 ?awk
sed
답변1
그리고awk
awk -v RS='' '/42B/' file
RS=
입력 레코드 구분 기호를 개행에서 빈 줄로 변경합니다. 레코드의 필드에 가 포함된 경우 /42B/
레코드를 인쇄합니다 .
''
(빈 문자열)은 빈 줄을 나타내는 데 사용되는 매직 값입니다.POSIX에 따르면:
만약에RS가 비어 있으면 레코드는 하나 이상의 빈 줄로 구성된 시퀀스로 구분됩니다
<newline>
. 선행 또는 후행 빈 줄은 입력의 시작이나 끝에서 빈 레코드가 되어서는 안 되며, a는<newline>
항상 필드 구분 기호가 되어야 합니다. 어떤 가치라도FS예.
출력 구분 기호는 여전히 단일 개행 문자이므로 출력 단락은 구분되지 않습니다. 출력 단락 사이에 빈 줄이 있는지 확인하려면 출력 레코드 구분 기호를 두 개의 줄 바꿈으로 설정하세요.
awk -v RS='' -v ORS='\n\n' '/42B/' file
답변2
데이터가 항상 원하는 전후의 줄로 구조화되어 있다고 가정하면 grep의 -A
(이후) 및 -B
(이전) 스위치를 사용하여 일치 전 한 줄과 일치 후 한 줄을 포함하도록 지시할 수 있습니다.
$ grep -A 1 -B 1 "42B" sample.txt
Pseudo name=Apple
Code=42B
state=fault
검색어 앞뒤에 동일한 줄을 원하는 경우 -C
(컨텍스트) 스위치를 사용할 수 있습니다.
$ grep -C 1 "42B" sample.txt
Pseudo name=Apple
Code=42B
state=fault
여러 줄을 일치시킬 때 더 엄격하게 일치시키려면 이 도구를 사용할 수 있습니다.pcregrep
, 여러 줄 패턴과 일치:
$ pcregrep -M 'Pseudo.*\n.*42B.*\nstate.*' sample.txt
Pseudo name=Apple
Code=42B
state=fault
위 패턴은 다음과 일치합니다.
-M
- 다중 라인'Pseudo.*\n.*42B.*\nstate.*'
"Pseudo"
- 첫 번째 문자열이 단어로 시작 하고 그 뒤에 줄 끝까지의 문자\n
, 그 문자열까지의 문자,"42B"
줄의 다른 쪽 끝까지의 문자(\n
) 가 이어지는 일련의 문자열과 일치합니다 . 마지막으로 문자 문자열"state"
뒤에는 임의의 문자가 옵니다.
답변3
일부 Unix 기반 grep
Unix 버전에는 -p
"단락" 플래그가 있습니다. 알아요AIX는.
grep -p 42B <myfile>
당신이 요청한 것을 정확하게 수행할 것입니다. YMMV와 GNU grep에는 이 플래그가 없습니다.
답변4
뒤에 빈 줄이 없는 또 다른 Perl 솔루션:
perl -00ne 'if ($_ =~ /42B/) {chomp($_); printf "%s\n",$_}' foo
예
% perl -00ne 'if ($_ =~ /42B/) {chomp($_); printf "%s\n",$_}' foo
Pseudo name=Apple
Code=42B
state=fault
% cat foo
Pseudo name=Apple
Code=42B
state=fault
Pseudo name=Prance
Code=43B
state=good