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


70

ログファイルを処理する場合、一部はgzip圧縮されたファイルにlogrotateなりますが、そうでないものもあります。したがって、次のようなことをしようとすると:

$ 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ますか?

NB:スクリプトを作成できることは知っていますが、既にツールがあるかどうかを尋ねています。

回答:


41

zless

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


この代替手段をありがとう。私はそれを考えることができました、私はできませんでしたか?;) ... しかたがない。スポットし、+ 1し、受け入れます(他の回答者よりも担当者が少ないためです)。
0xC0000022L

すごい。私は何年もそれを解決するためにシェルスクリプトを使用していました...または恐ろしいperlスクリプト... awstatsによって使用されるログ解決マージ...今、私はこの素晴らしいツールを知っています。ありがとう。
ルチアーノアンドレスマティーニ

98

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

zcat -f -- *

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

exec gzip -cd "$@"

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

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

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

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

また:

grepたとえば、出力をパイプすることができます

あなたはそのために使うことができますzgrep

zgrep -- PATTERN *

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


1
おかげで、それはzlessソリューションの興味深い代替案です。素敵で+1。
0xC0000022L

6
両方のことに注意してくださいzlesszgrep呼ぶのですかあるスクリプトgzip -cdfq(つまりzcat -fq)。
ステファンシャゼル

9

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

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

同僚の教育に費やす時間が最小限で済むため、このアプローチが気に入っています。ログメッセージの並べ替えに適したタイムスタンプにタイムスタンプがある場合、これは特に便利です。
トーマスL Holaday

優れたアプローチ。ありがとう。
ミロシュチャコノヴィッチ

7

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

debian wheezy以降、おそらくredhat / centosでも利用可能です。

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

ここでutilの使用法を説明するブログ投稿(noone.org


3

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

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


2

圧縮されたものと圧縮されていないものの両方を時系列で開きます。

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

10個を超えるログファイル(syslog.10.gz ...)で誤った順序を示します
Vanni

良いキャッチ。-vはそれを修正するはずです。
ライアン

ls -rv避けるためにtac。ログファイルの場合は、less $(ls -rv syslog*)お使いでLESSOPENのenv varが設定され、適切に適しています。esc-nファイルの境界を無視して、ファイル全体を検索して次の一致を見つけることができます。
ピーターコーデス

With zshzcat -f syslog*(nOn)
ステファンシャゼラス

あなたのログが次の日を圧縮するために設定して回転している場合、これは動作しません
cjbarth

1

ラッパーはどうですか?

$ 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

0

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

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

今、あなたは、例えば入力できるlogs /var/log/sysloglogs /var/log/nginx/access.log確認するために、すべてのsyslogまたはnginxのと古いものから最新のログメッセージを少ないです

次に、次の文字を入力してヒットするものを検索できます。/somethingn


0

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

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

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

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


  • 0

    @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対応するためにステートメントの最初の部分を変更する必要があります。

    弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
    Licensed under cc by-sa 3.0 with attribution required.