압축 파일에서 텍스트를 검색하고 파일 이름만 가져오는 방법

압축 파일에서 텍스트를 검색하고 파일 이름만 가져오는 방법

특정 문자열이 포함된 파일 이름만 찾으려고 합니다. 파일이 압축되었습니다( .gz).

설치가 안되어 있어서 zgrep설치할 수가 없습니다. 그래서 그 옵션을 사용할 수 없습니다 -l.

gzipand gunzip옵션을 사용 -c하고 pipping을 시도했지만 grep -l작동하지 않습니다. 또한 pipping을 사용해 보았지만 zcat그것도 작동하지 않습니다. 어떤 단서가 있나요?

(참고: 운영 체제는 Solaris 10입니다.)

답변1

zgrep 작업을 수동으로 수행할 수 있습니다. 파일 이름만 필요하므로 패턴 grep이 있는지 테스트하고 패턴이 발견되면 파일 이름을 인쇄하기 위한 것입니다.

#!/bin/sh
pattern=$1; shift
PATH=`getconf PATH`:$PATH # needed on Solaris 10 and earlier
                          # to get a standard grep
export PATH
found=0
for x do
  if case "$x" in
      *.gz|*.[zZ]) <"$x" gzip -dc | grep -q -e "$pattern";;
      *) <"$x" grep -q -e "$pattern";; 
     esac
  then
    found=1
    printf '%s\n' "$x"
  fi
done
if [ $found -eq 0 ]; then exit 1; fi

작동 모드는 다음과 같습니다.

that-script 'pattern' file1 file2.gz file3.Z file.*.gz ...

Solaris 10 실행을 위한 일부 특정 지침(이전 버전 및 어느 정도 Solaris 11에도 적용 가능)

  • 이러한 시스템에서는 /bin/sh표준 POSIX 대신 Bourne 쉘이 사용됩니다 sh. #! /usr/xpg4/bin/sh -표준을 얻기 위해 she-bang을 변경 sh하거나 여기서 한 것처럼 고대 Bourne 구문으로 제한할 수 있습니다(그래서 no $(...), no case $x in (x)...)(Solaris 11은 이제 이를 구현하기 위해 POSIX 호환 쉘을 사용합니다( ksh93). /bin/sh)).
  • 이러한 시스템에서는 이전과 같이 압축된 파일 만 zcat처리됩니다 . 파일을 호출해야 합니다 ..Zcompressgzip.gz
  • 기본적으로 표준 유틸리티를 반드시 얻을 수는 없습니다. 예를 들어 기본값은 고대 grep옵션 /usr/bin이며 표준 옵션을 지원하지 않습니다 -q. 표준 유틸리티를 얻으려면 $PATH표준 유틸리티가 있는 경로(예: 출력 )를 업데이트해야 합니다 getconf PATH.

아카이브 멤버 이름과 라인 번호 또는 내용을 표시하려면 grep에서 라인 데이터를 가져와야 하며 스크립트에서 멤버 이름을 가져와야 합니다. 호출에서 -q옵션 을 제거 grep하고 해당 내용을 사후 처리합니다.

#!/bin/ksh
pattern=$1; shift
export PATH="$(getconf PATH):$PATH" # needed on Solaris 10 and earlier
                                    # to get a standard grep
found=0
for x do
  case "$x" in
      *.gz|*.[zZ]) <"$x" gzip -dc | grep -n -e "$pattern";;
      *) <"$x" grep -n -e "$pattern";; 
  esac | {
    filename=$x awk '{print ENVIRON["filename"] ":" $0; found=1}
                     END {exit(!found)}' && found=1
  }
done
if [ $found -eq 0 ]; then exit 1; fi

답변2

파일은 실제로 tar.gz 파일이므로 압축도 풀어야 합니다. Tar는 여러 파일(귀하의 경우 하나만)을 함께 묶는 보관 유틸리티이며 원래 데이터를 테이프 드라이브에 백업하는 데 사용되었습니다.

tar 유틸리티는 처음에 콘텐츠를 압축하지 않으므로 일반적으로 압축을 위해 gzip 또는 기타 유틸리티를 통해 스트리밍됩니다. tar.gz의 압축을 풀어도 tar 구현 계층은 그대로 유지되므로 작동하지 않습니다.

이제 gun tar는 "z" 명령을 사용하여 단일 명령으로 tar 및 zip 압축을 수행합니다.

따라서 원하는 작업을 수행하려면 tar를 사용하여 파일 대상 "f"에서 "x"를 추출하고 "z"의 압축을 풀고 stdout "O"로 스트리밍한 다음 grep으로 파이프해야 한다고 생각합니다. 다음과 같아야 합니다.

 tar -xzf mycompressedlogfile.tar.gz -O | grep -l "pattern"

귀하의 tar 버전에는 -z가 없으므로 greping하기 전에 tar를 통해 gzip의 출력을 파이핑해 보십시오.

 gzip -dc mycompressedlogfile.tar.gz | tar -xOf - | grep -l "pattern"

그러나 나는 tar의 Solaris 10 버전이 tar 내용을 stdout으로 스트리밍하기 위한 "O" 옵션을 지원하지 않는다고 생각합니다. :( 작업 디렉토리의 모든 파일에 대해 위의 작업을 수행해야 할 수도 있습니다(O 없이 "tar -xf -"). 아니면 어떻게든 생성한 파일을 해석할 수 있는지 확인하고, 죄송합니다. 단, 솔라리스에서 할 수 없는 경우에는 검색해 보세요. 머신에 gnu-tar를 설치합니다.

선택한 답변에서 tar 스트림에서 패턴을 검색하고(압축되지 않았기 때문에 의미가 있다고 생각합니다) 거기에서 알아낼 수 있다고 생각합니다. :) 좋습니다.

답변을 얻으셨다니 다행입니다.

답변3

또 다른 해결책은 다음과 같습니다.

#!/bin/bash
# Grab the pattern, just like grep
re="$1"; shift

# Loop across the remaining arguments, or stdin if none
test 0 -eq $# && set -- -
for file
do
    # Search through the file (compressed or otherwise)
    zcat -f "$file" | grep -q "$re" && echo "$file"
done

파일에 복사하고 해당 파일을 실행 가능하게 만든 다음 chmod a+x {filename}다음과 같이 사용해야 합니다 zgrep.

mkdir -p ~/bin
export PATH="$HOME/bin:$PATH"  # Add the ~/bin directory to your PATH. Also add this line to your ~/.profile

cat > ~/bin/mygrep             # Paste the file at this point, hit Ctrl/D on a blank line to end. Or otherwise edit ~/bin/mygrep
chmod a+x ~/bin/mygrep         # Make it executable

mygrep 'hello.*world' a*       # Search for the RE 'hello.*world' in all files beginning with 'a'

zcat -f거나 grep -q인식되지 않으면 각각을 다음으로 바꿀 수 있습니다

( zcat "$file" 2>/dev/null || cat "$file" )    # zcat -f "$file"
grep "$re" 2>/dev/null                         # grep -q "$re"

두 대체를 모두 적용한 후 결과 대체 라인은 다음과 같습니다.

( zcat "$file" 2>/dev/null || cat "$file" ) | grep "$re" 2>/dev/null && echo "$file"

관련 정보