Esiste uno strumento che combina zcat e cat in modo trasparente?


71

Quando si gestiscono i file di registro, alcuni finiscono come file compressi con gzip logrotatee altri no. Quindi quando provi qualcosa del genere:

$ zcat *

si finisce con una riga di comando come zcat xyz.log xyz.log.1 xyz.log.2.gz xyz.log.3.gze quindi con:

gzip: xyz.log: not in gzip format

Esiste uno strumento che prenderà i byte magici, simile a come filefunziona, e utilizzi zcato catdipende dal risultato in modo che io possa ad grepesempio inviare l'output ?

NB: So di poterlo scrivere, ma sto chiedendo se esiste già uno strumento.

Risposte:


41

zless

Sembra un peccato zcat, poiché libz ha un'API che supporta la lettura di file compressi e non compressi in modo trasparente. Ma la manpage dice che zcatè equivalente a gunzip -c.


Grazie per questa alternativa Ci avrei pensato, no? ;) ... Oh bene. Spot on, +1 e accetta (anche perché hai meno rep rispetto all'altro risponditore).
0xC0000022L

Sorprendente. Mi ha aiutato molto, stavo usando lo script di shell per risolverlo da anni ... o un terribile script perl ... registro risoluzione unione, usato da awstats ... ora conosco questo fantastico strumento. Grazie.
Luciano Andress Martini,

99

Provalo con -fo --force:

zcat -f -- *

Dato che zcatè solo un semplice script che viene eseguito

exec gzip -cd "$@"

con lunghe opzioni che si tradurrebbero in

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

e, come da man gzip(enfatizzare il mio):

-f --force
      Forza la compressione o decompressione anche se il file ha più collegamenti
      o il file corrispondente esiste già o se i dati compressi lo sono
      letto o scritto su un terminale. Se i dati di input non sono in un formato
      riconosciuto da gzip e se viene fornita anche l'opzione --stdout, copia il file
      inserire i dati senza modificare l'output standard: lasciare che zcat si comporti come cat .

Anche:

in modo da poter reindirizzare l'output ad grepesempio

Puoi usare zgrepper quello:

zgrep -- PATTERN *

comunque vedi il commento di Stéphane sotto.


1
Grazie, è un'interessante alternativa alla zlesssoluzione. Nizza e +1.
0xC0000022L

6
Si noti che entrambi zlesse zgrepsono script che chiamano gzip -cdfq(cioè zcat -fq).
Stéphane Chazelas,

9

Uso esattamente per lo stesso scopo:

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

Mi piace questo approccio perché richiede il minor tempo dedicato all'istruzione dei colleghi. Se i messaggi di registro hanno un timestamp in un timestamp facile da ordinare, questo è particolarmente utile.
Thomas L Holaday,

Approccio eccellente Grazie.
Miloš Đakonović,

7

Esiste una sostituzione drop-in per ztools (zcat, zgrep, ..) chiamata zutils che unisce tutti gli strumenti di decompressione indipendentemente dal back-end. Quindi con lo stesso comando puoi leggere in modo trasparente file plain, lzma, gzipped, xz.

È disponibile in debian wheezy o più recente, probabilmente anche in redhat / centos.

La pagina del progetto è qui nongnu.org

Un post sul blog che spiega l'uso dell'utilità qui ( noone.org )


3

Funziona bene in RHEL 5.x dove zcat è un file binario. Non riesce in RHEL 6.x (e Ubuntu 12.x) in cui zcat è uno script. Questo usato per funzionare bene.

Non userei affatto zcat ma neanche zgrep non gestirà correttamente i file non compressi.


2

Apre sia compressi che non compressi, in ordine cronologico.

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

Fornisce un ordine errato con più di dieci file di registro (syslog.10.gz ...)
Vanni

Buona pesca. -v dovrebbe risolverlo.
Ryan,

ls -rvda evitare tac. Per i file di registro, less $(ls -rv syslog*)con il tuo LESSOPENvar var impostato correttamente funziona bene. Puoi cercare tra i file esc-nper trovare la corrispondenza successiva, ignorando i limiti dei file.
Peter Cordes,

Con zsh:zcat -f syslog*(nOn)
Stéphane Chazelas,

Questo non funziona se il tuo registro ruota impostato per comprimere il giorno successivo
cjbarth,

1

Che dire di wrapper?

$ 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

Copia e incolla (o mettilo alla fine del tuo ~/.bashrcfile) questa funzione bash :

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

Ora è possibile digitare ad esempio logs /var/log/syslogo logs /var/log/nginx/access.logper vedere tutti i syslog o nginx messaggi di log dal più vecchio al più recente con meno .

È quindi possibile cercare qualcosa digitando /somethinge colpendo nper il prossimo .


0

C'è un bellissimo script perl che lo fa esattamente. È logresolvemerge.pl del progetto awstats: http://www.awstats.org/docs/awstats_tools.html

Logresolvemerge ti consente di ottenere un unico file di registro di output, ordinato per data, creato da fonti particolari:

  • Può leggere diversi file di registro di input
  • Può leggere i file di registro .gz / .bz2

    L'output è su STDOUT, in modo da poterlo utilizzare abbastanza bene in processi aggiuntivi.


  • 0

    Sulla base della risposta di @ Ryan, ciò che segue otterrà l'ordinamento alfabetico di tutti i file "rolled", quindi il file corrente, decomprimili, se necessario, e lessloro:

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

    o se si desidera ottenerli tutti come flusso continuo, è possibile taileseguirli e, facoltativamente, reindirizzare a un altro processo

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

    Devo notare che questo è progettato per i registri che vengono ruotati quotidianamente con la data aggiunta alla fine del file. Se ci registri in un formato diverso, dovrai modificare la prima parte catdell'istruzione per adattarla.

    Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
    Licensed under cc by-sa 3.0 with attribution required.