grepを使わずにgzファイルから検索キーワードの最初の数行を印刷する方法は?

grepを使わずにgzファイルから検索キーワードの最初の数行を印刷する方法は?

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番号を印刷したいです。 3行目には必ずしも「プロファイルなし」は表示されません。どの行にも表示できます。私のオペレーティングシステムは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(またはzcatLinuxの場合)gzipファイルの内容を標準出力として印刷します。
  • awk次に文字列を検索し、"No Profile Data"最初の2行を印刷します。

答え2

編集済み

新しい方法:改行を削除します。

各gzip圧縮ファイルに1つの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すべての行を1つに折りたたんでから始まらないすべての行を削除し、一致するファイルから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'
  • paste3本のワイヤで構成される各グループを接続します。
  • 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'

これにより、一度に3行の入力のみがスキャンされます。各行は\nパターン空間で改行で区切られます。各N新しい行をインポートすると、最も古い行がD削除されます。\n.*No Profileパターン空間で正規表現が一致したことがある場合(パターン空間の最新行の場合、2番目の最新行の場合は次のサイクル)、最も古い行を印刷します。したがって、以前に発生した2行が得られます。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フィールドで、一致の前の2行が見つかる場合にのみ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前に2行が出なければなりません。No Profileマッチ。

関連情報