grep
.gz 파일을 사용하지 않고 검색 키워드 앞의 행을 인쇄하려면 어떻게 해야 합니까?
ID:342N000390AAAAAAAA 07/14/15 10:26 (MV90 )
* Register Data Imported
* Warning - No Profile Data
07/14/15 10:24 05/13/15 08:16 15 1 5956
No Profile
키워드를 검색하고 342N000390AAAAAAAAA인 ID 번호를 인쇄하고 싶습니다 . 세 번째 줄에는 반드시 "프로필 없음"이 나타나지 않습니다. 어떤 줄에도 나타날 수 있습니다. 내 운영 체제는 HP-UX이므로 많은 명령을 사용할 수 없습니다.
답변1
당신이 사용할 수있는 awk
:
gzcat file.gz | awk '/No Profile Data/{printf "%s\n%s\n%s\n", b, a, $0} {b=a;a=$0}'
gzcat
(또는zcat
Linux의 경우) gzip 파일의 내용을 표준 출력으로 인쇄합니다.awk
그런 다음 문자열을 검색"No Profile Data"
하고 처음 두 줄을 인쇄하십시오.
답변2
편집됨
새로운 방법: 줄바꿈을 제거합니다.
각 gzip 압축 파일에 하나의 ID만 있다고 가정하면 다음을 시도해 볼 수 있습니다.
gunzip -c file.gz | sed -e ':a;N;$!ba;s/\n/ /g' -e '/^[[:space:]]/d' -e 's/^ID:\([[:alnum:]]*\).*Warning - No Profile Data.*/\1/' -e '/^ID:/d'
gunzip -c
파일을 추출하여stdout
sed
모든 줄을 하나로 접은 다음 으로 시작하지 않는 모든 줄을 제거한ID:
다음 일치하는 파일에서 ID를 추출한 다음 ID가 표시되거나 아무것도 표시되지 않는 파일과 일치하지 않는 줄을 제거합니다. .
크레딧에 귀속됨https://stackoverflow.com/a/1252191/5148242그리고https://unix.stackexchange.com/a/218094/124507@黑心
원래
grep
여전히 적합한 옵션이지만 연습을 위해 sed
결과 및 paste
부품 찾기를 사용할 수 있습니다 -B2
.
zcat nogrep.gz | paste - - - | sed -e '/^[[:space:]]/d' -e 's/^ID:\([[:alnum:]]*\).*Warning - No Profile Data/\1/' -e '/^ID:/d'
paste
3개의 전선으로 구성된 각 그룹을 연결합니다.sed
시작하지 않는 모든 줄을 삭제하고ID:
일치하는 파일에서 ID를 추출한 다음ID:
파일과 일치하지 않는 줄을 삭제하여 ID가 표시되거나 아무것도 표시되지 않도록 합니다.
답변3
(희망)최종 제품
find . -name \*.gz -type f -exec gzcat {} + |
sed -ne'/^ *ID:/h;/No Profile/!d;x' \
-e's/^ *ID:\([^ ]*\).*/\1/p'
따라서 이는 find
파일 이름이 패턴과 일치하는 현재 디렉토리의 모든 일반 파일을 재귀적으로 루트 *.gz
하고 zcat
단일 스트림의 각 파일을 sed
표준 입력으로 반복적으로 압축 해제하기 위해 가능한 한 적은 횟수를 호출합니다.
sed
문자열로 시작하는 줄에 대한 입력을 검색합니다.*ID:
. 발견되면 h
이전 복사본을 만든 다음 다음을 찾습니다.No Profile
또한 d
일치하지 않는 모든 행을 삭제합니다. 발견되면 sed
예약된 공간으로 교체하고 정리를 시도합니다.^ *ID:
:
행은 첫 번째 항목과 다음 항목 사이의 부분에만 있습니다.<스페이스>. 성공하면 sed
p
결과를 인쇄합니다.
~처럼@DarkHeart가 지적했습니다.그러나 HPUX 시스템에서는 zcat
명령 이름을 으로 변경 해야 할 가능성이 높습니다.gzcat
다양성
이것은 문자열 일치 직전에 발생하는 행 쌍을 단일 파일에서 검색하는 데 필요한 전부입니다.No Profile
:
gzip -d <file.gz |
sed -e'1N;$!N;/\n.*No Profile/P;D'
이렇게 하면 한 번에 세 줄의 입력만 스캔됩니다. 각 라인은 \n
패턴 공간에서 줄바꿈으로 구분됩니다. 각각의 N
새 행을 가져오면 가장 오래된 행이 D
삭제됩니다. \n.*No Profile
패턴 공간에서 정규식이 일치한 적이 있는 경우(패턴 공간에서 가장 최근 행인 경우, 두 번째 최신 행인 경우 다음 사이클), 가장 오래된 행을 인쇄합니다. 따라서 이전에 발생한 두 줄을 얻게 됩니다.No Profile
. 발견된 행도 인쇄하려면...
gzip -d <file.gz |
sed -e'1N;$!N;/No Profile/P;D'
그리고 find
:
find . -name \*.gz -type f -exec zcat {} + |
sed -e'1N;$!N;/No Profile/P;D'
원하는 경우 .
이를 디렉터리 이름으로 바꿀 수 있습니다. 추가할 수도 있습니다.\n.*No Profile
일치하는 줄이 인쇄되는 것을 방지하려면 비트를 사용하세요. 이 명령 .
은 귀하의 취향에 맞지 않으면 다음과 같이 반복됩니다 .
find . \! -name . -prune -name \*.gz \
-type f -exec zcat {} + |
sed -e'1N;$!N;/No Profile/P;D'
특별히 선두를 찾고 있다면ID
필드이며 일치 항목 앞의 두 행을 찾을 수 있는 경우에만No Profile
넌 할 수있어:
find . -name \*.gz -type f -exec zcat {} + |
sed -ne'/^ID/!D;/\n/!N;N' \
-e's/ .*\n.*\n.*No Profile.*//p;D'
...이것은 선두만 인쇄합니다ID
필드는 모든/전체에 나타날 수 있습니다.*.gz
파일 find
호출 zcat
인쇄 및 다음 경우에만ID
앞에 두 줄이 나와야 합니다.No Profile
성냥.