다음은 파일의 텍스트입니다.
Pseudo name=Apple Code=42B state=fault Pseudo name=Prance Code=43B state=good
“42B”를 입력하고 위의 텍스트에서 다음과 같은 출력을 얻습니다.
Pseudo name=Apple Code=42B state=fault
누군가 grep
/ awk
/ sed
?
댓글
- " grep "로이 질문에 태그를 지정했습니다. 그렇다면 " grep " 솔루션 만 찾고 계십니까? 질문에서 awk & sed도 지정합니다. 이러한 태그를 추가 할 수 있습니까? 어제 밤에 질문을 편집했을 때 ' 당신의 의도를 확신하지 못했습니다.
- stackoverflow.com/ 질문 / 12024410 / …
답변
awk
awk -v RS="" "/42B/" file
RS=
를 사용하면 입력 레코드 구분 기호가 변경됩니다. 개행에서 빈 줄로. 레코드의 필드에 /42B/
가 포함 된 경우 레코드를 인쇄합니다.
""
(null 문자열)은 마법입니다. POSIX에 따라 빈 줄을 나타내는 데 사용되는 값 :
If RS 가 null이면 레코드가
<newline>
와 하나 이상의 공백으로 구성된 시퀀스로 구분됩니다. 행, 선행 또는 후행 공백 행은 입력의 시작 또는 끝에 빈 레코드를 생성하지 않으며<newline>
는 FS 입니다.
출력 단락은 출력 구분자가 하나의 줄 바꿈으로 유지되기 때문에 구분해야합니다. 출력 단락 사이에 빈 줄이 있는지 확인하려면 출력 레코드 구분 기호를 두 줄 바꿈으로 설정합니다.
awk -v RS="" -v ORS="\n\n" "/42B/" file
댓글
- 멋진 솔루션을위한 +1. 하지만 ' 파일을 리디렉션 할 필요는 없습니다 …
- 손가락이 자동 조종 장치에있었습니다.
- @jasonwryan (액세스가 필요하지 않은 경우) awk (
FILENAME
) 내의 파일 이름으로 변경하면 ' '를 포함하는 파일 이름에 대한 문제를 방지하므로 리디렉션을 사용하는 것이 좋습니다. div id = “c221affd33″>
또는 -
로 시작 (또는 -
)하면 일관된 오류 메시지가 생성됩니다. awk
실행을 방지하거나 입력 파일을 열 수없는 경우 ' 다른 리디렉션을 수행하지 않습니다.
답변
데이터가 항상 구조화되어 있다고 가정하면 grep의
(이후) 및 -B
(이전)는 일치 전 1 줄과 그 뒤 1 줄을 포함하도록 전환합니다.
$ 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
If 여러 줄을 일치시킬 때 좀 더 엄격하게하려면 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"
다음에 임의의 문자가옵니다.
댓글
- iv id = “aa80db42c4
-A
및-B
가 동일한 경우 “>
(컨텍스트)를 바로 가기로 사용할 수 있습니다.
답변
grep
Unix의 일부 버전에는 “paragraph”에 대한 -p
플래그가 있습니다. 저는 AIX가 한다는 것을 알고 있습니다.
grep -p 42B <myfile>
당신이 원하는 것을 정확히 할 것입니다. . YMMV 및 GNU grep에는이 플래그가 없습니다.
코멘트
- -p 플래그가 있으면 좋을 것입니다. 특히 -v와 함께 사용하면 출력에서 전체 단락을 제외 할 수 있습니다.
답변
아마도 awk를 사용하는 것과 비슷하게 쉬운 방법이 있지만 perl에서는 다음과 같습니다.
cat file | perl -ne "BEGIN { $/="\n\n" }; print if $_ =~ /42B/;"
기본적으로 파일을 빈 줄로 구분 된 청크로 분할 한 다음 정규 표현식과 일치하는 청크 만 인쇄하도록합니다.
설명
답변
후행 빈 줄 :
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
댓글
- 또는 triplee이 댓글에 쓴대로 더 짧아 지므로 더 읽기 쉽습니다.
perl -00 -ne 'print if /42B/' file
li>