圧縮ファイルからテキストを検索し、ファイル名のみを取得する方法

圧縮ファイルからテキストを検索し、ファイル名のみを取得する方法

特定の文字列を含むファイル名のみを検索します。ファイルが圧縮されました(.gz)。

インストールができていないためzgrepインストールできません。したがって、そのオプションは使用できません-l

gzipandgunzipオプションを使用-cして pipping しようとしましたが、grep -l動作しません。また、ピッピングを試してみましたが、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は、複数のファイル(1つのみ)をまとめたアーカイブユーティリティで、元のデータをテープドライブにバックアップするために使用されました。

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 -")、または何らかの方法で生成されたファイルを解釈できるかどうかを確認して申し訳ありませんが、Solarisではできない場合は、検索してみてください。マシンに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"

関連情報