web-dev-qa-db-ja.com

zcatとcatを透過的に組み合わせるツールはありますか?

ログファイルを処理するとき、一部はlogrotateのおかげでgzip圧縮されたファイルになり、他のファイルはそうではありません。したがって、次のようなことを試みると、

$ zcat *

あなたはzcat xyz.log xyz.log.1 xyz.log.2.gz xyz.log.3.gzのようなコマンドラインで終わり、次に:

gzip: xyz.log: not in gzip format

fileの動作と同様に、マジックバイトを取得し、結果に応じてzcatまたはcatを使用して、たとえばgrepにパイプで出力できるツールはありますか?

注意:私はそれをスクリプト化できることを知っていますが、私はすでにそこにツールがあるかどうかを尋ねています。

75
0xC0000022L

zless

Libzには、圧縮ファイルと非圧縮ファイルの両方からの透過的な読み取りをサポートするAPIがあるため、zcatは残念です。しかし、マンページには、zcatgunzip -cと同等であると記載されています。

41
sourcejedi

-fまたは--forceでお試しください:

zcat -f -- *

zcatは実行する単純なスクリプトなので

exec gzip -cd "$@"

に変換される長いオプション

exec gzip --stdout --decompress "$@"

そして、man gzipに従って(鉱山を強調):

-f --force
ファイルに複数のリンクがある場合や、対応するファイルがすでに存在する場合、または圧縮されたデータが端末から読み取られたり書き込まれたりした場合でも、強制的に圧縮または解凍します。
 入力データがgzipで認識される形式
ではなく、オプション--stdoutも指定されている場合は、
入力データを変更せずに標準出力にコピーします。 zcatに猫として振る舞わせる

また:

出力をgrepにパイプできるように

そのためにzgrepを使用できます。

zgrep -- PATTERN *

ただし、以下のステファンのコメントを参照してください。

105
don_crissti

私はまったく同じ目的で使用します:

{ cat /var/log/messages ; zcat /var/log/messages*.gz ; }| grep something | grep "something else" ....
11
Washuu

バックエンドとは無関係にすべての解凍ツールを統合するzutilsと呼ばれるztools(zcat、zgrep、..)のドロップイン置き換えがあります。したがって、同じコマンドを使用して、プレーン、lzma、gzipped、xzファイルを透過的に読み取ることができます。

Debian wheezy以降で利用できます。おそらくredhat/centosでも利用できます。

プロジェクトのページはこちら nongnu.org

ここでユーティリティの使用法を説明するブログ投稿( noone.org

7
aseques

これは、zcatがバイナリであるRHEL 5.xで正常に機能します。 zcatがスクリプトであるRHEL 6.x(およびUbuntu 12.x)では失敗します。これはsedで正常に動作します。

私はzcatをまったく使用しませんが、zgrepは非圧縮ファイルも適切に処理しません。

3
Peter Laws

時系列で圧縮と非圧縮の両方を開きます。

ls -v syslog* | tac | xargs zcat -f | less
2
Ryan

ラッパーはどうですか?

$ cat xcat.sh 
#!/bin/bash

for i in $@;do 
        [ ! -z "$(file -i $i | grep "gzip")" ] && zcat $i || cat $i
done

$ bash xcat.sh plain.txt gzipped_text.gz
1
ConcealmEnt

次のbash関数をコピーして貼り付けます(または~/.bashrcファイルの最後に貼り付けます)。

logs() { zcat -f $(ls -rv "$1"*) | less; }

これで、たとえばlogs /var/log/syslogまたはlogs /var/log/nginx/access.logと入力して、all thesyslogまたはnginxlessを使用して、メッセージを古いものから新しいものにログします。

次に、somethingを検索して、/somethingと入力し、nを押してnext

0
Vanni

これを正確に行う美しいPerlスクリプトがあります。これは、awstatsプロジェクトのlogresolvemerge.plです。 http://www.awstats.org/docs/awstats_tools.html

Logresolvemergeを使用すると、特定のソースから構築された、日付順にソートされた1つの一意の出力ログファイルを取得できます。

  • 複数の入力ログファイルを読み取ることができます
    • .gz/.bz2ログファイルを読み取ることができます。

      出力はSTDOUTにあるため、追加のプロセスで非常にうまく利用できます。

  • 0
    Daniel Andersen

    @Ryanの答えに基づいて、次のコードはすべての「ロール」ファイルをアルファベット順に並べ替えて取得し、現在のファイルを取得し、必要に応じて解凍し、lessします。

    cat <(ls mylog.log-* | sort) <(ls mylog.log) | xargs zcat -f | less

    または、すべてを連続ストリームとして取得したい場合は、それらをtailし、オプションでそれを別のプロセスにパイプすることができます。

    cat <(ls mylog.log-* | sort | xargs zcat -f) <(tail -f -n +0 mylog.log)

    これは、ファイルの末尾に日付が追加されて毎日ローテーションされるログ用に設計されていることに注意してください。ログに別のフォーマットが記録されている場合は、対応するようにcatステートメントの最初の部分を変更する必要があります。

    0
    cjbarth