Existe-t-il un outil combinant zcat et cat de manière transparente?

71

Lors de la gestion des fichiers journaux, certains fichiers finissent par être compressés, d' logrotateautres non. Alors, quand vous essayez quelque chose comme ça:

$ zcat *

vous vous retrouvez avec une ligne de commande comme zcat xyz.log xyz.log.1 xyz.log.2.gz xyz.log.3.gzet ensuite avec:

gzip: xyz.log: not in gzip format

Existe-t-il un outil qui prend les octets magiques, similaire à la façon dont filefonctionne, et utilise zcatou catdépend du résultat afin que je puisse diriger la sortie vers greppar exemple?

NB: Je sais que je peux le scripter, mais je demande s'il existe déjà un outil.

0xC0000022L
la source

Réponses:

41

zless

Cela semble dommage zcat, car libz a une API qui prend en charge la lecture de fichiers compressés et non compressés de manière transparente. Mais la page de manuel dit que cela zcatéquivaut à gunzip -c.

sourcejedi
la source
Merci pour cette alternative. J'aurais pu y penser, n'est-ce pas? ;) ... tant pis. Spot sur, +1 et accepter (également parce que vous avez moins de représentants que l’autre répondant).
0xC0000022L
Incroyable. Je me suis beaucoup aidé, j’utilisais un script shell pour résoudre ce problème pendant des années ... ou un terrible script perl ... la résolution du journal fusionné, utilisée par awstats ... maintenant je connais cet outil incroyable. Merci.
Luciano Andress Martini
99

Essayez avec -fou --force:

zcat -f -- *

Depuis zcatest juste un script simple qui s'exécute

exec gzip -cd "$@"

avec de longues options qui se traduiraient par

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

et, comme indiqué dans man gzip(souligner le mien):

-f --force
      Forcer la compression ou la décompression même si le fichier contient plusieurs liens
      ou le fichier correspondant existe déjà, ou si les données compressées sont
      lu ou écrit sur un terminal. Si les données d'entrée ne sont pas dans un format
      reconnu par gzip, et si l'option --stdout est également donnée, copiez le
      Données d'entrée sans modification de la sortie standard: laissez zcat se comporter comme un chat .

Aussi:

afin que je puisse canaliser la sortie à greppar exemple

Vous pouvez utiliser zgreppour cela:

zgrep -- PATTERN *

voir cependant le commentaire de Stéphane ci-dessous.

don_crissti
la source
1
Merci, c'est une alternative intéressante à la zlesssolution. Nice et +1.
0xC0000022L
6
Notez que les deux zlesset zgrepsont des scripts qui appellent gzip -cdfq(c'est-à-dire zcat -fq).
Stéphane Chazelas
9

J'utilise exactement dans le même but:

{ cat /var/log/messages ; zcat /var/log/messages*.gz ; }| grep something | grep "something else" ....
Washuu
la source
J'aime cette approche car elle nécessite le moins de temps possible pour éduquer ses collègues. Si les messages de journal ont un horodatage dans un horodatage convivial, cela est particulièrement utile.
Thomas L Holaday
Excellente approche. Merci.
Miloš Đakonović
7

Il existe un remplacement instantané pour ztools (zcat, zgrep, ..) appelé zutils qui unit tous les outils de décompression indépendamment du serveur. Donc, avec la même commande, vous pouvez lire des fichiers en clair, lzma, gzippés, xz de manière transparente.

Il est disponible dans debian Wheezy ou plus récent, probablement aussi dans redhat / centos.

La page du projet est ici nongnu.org

Un article de blog expliquant l'utilisation de l'util ici ( noone.org )

aseques
la source
3

Cela fonctionne très bien dans RHEL 5.x où zcat est un binaire. Il échoue dans RHEL 6.x (et Ubuntu 12.x), où zcat est un script. Cela utilisé pour fonctionner correctement.

Je n'utiliserais pas du tout zcat mais zgrep ne gérera pas correctement les fichiers non compressés non plus.

Peter Laws
la source
2

Ouvre à la fois compressé et non compressé, dans l'ordre chronologique.

ls -v syslog* | tac | xargs zcat -f | less
Ryan
la source
Il donne un ordre erroné avec plus de dix fichiers journaux (syslog.10.gz ...)
Vanni
Bonne prise. -v devrait résoudre ce problème.
Ryan
ls -rvà éviter tac. Pour les fichiers journaux, less $(ls -rv syslog*)avec votre LESSOPENvariable var, le jeu fonctionne correctement. Vous pouvez effectuer une recherche dans les fichiers avec esc-npour trouver la correspondance suivante, en ignorant les limites des fichiers.
Peter Cordes
Avec zsh:zcat -f syslog*(nOn)
Stéphane Chazelas
Cela ne fonctionne pas si votre journal tourne pour compresser le lendemain
cjbarth
1

Qu'en est-il de l'emballage?

$ 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
Dissimulation
la source
0

Copiez et collez (ou mettez-le à la fin de votre ~/.bashrcfichier) cette fonction bash :

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

Vous pouvez maintenant taper par exemple logs /var/log/syslogou logs /var/log/nginx/access.logpour voir tous les messages du journal syslog ou nginx du plus ancien au plus récent avec moins .

Vous pouvez ensuite rechercher quelque chose en tapant /somethinget en tapant npour la suivante .

Vanni
la source
0

Il y a un beau script Perl qui fait exactement cela. C'est logresolvemerge.pl du projet awstats: http://www.awstats.org/docs/awstats_tools.html

Logresolvemerge vous permet d’obtenir un fichier journal de sortie unique, trié par date et construit à partir de sources particulières:

  • Il peut lire plusieurs fichiers journaux d'entrée
  • Il peut lire les fichiers journaux .gz / .bz2

    La sortie est sur STDOUT, afin que vous puissiez l'utiliser assez facilement dans des processus supplémentaires.

  • Daniel Andersen
    la source
    0

    En s'appuyant sur la réponse de @ Ryan, les éléments suivants obtiendront tous les fichiers 'roulés' triés par ordre alphabétique, puis le fichier en cours, décompressez-les, si nécessaire, et procédez comme suit less:

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

    ou si vous voulez tous les obtenir en tant que flux continu, vous pouvez tailles diriger et éventuellement les diriger vers un autre processus.

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

    Je devrais noter que cela est conçu pour les journaux qui font l'objet d'une rotation quotidienne avec la date ajoutée à la fin du fichier. Si votre journal nous enregistre sous un format différent, vous devrez modifier la première partie de la catdéclaration afin de l'adapter.

    cjbarth
    la source