web-dev-qa-db-fra.com

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

Lors de la gestion des fichiers journaux, certains finissent sous forme de fichiers compressés grâce à logrotate et d'autres non. Donc, 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.gz puis avec:

gzip: xyz.log: not in gzip format

Existe-t-il un outil qui prendra les octets magiques, semblable au fonctionnement de file, et utilisera zcat ou cat selon le résultat pour que je puisse diriger la sortie vers grep par exemple?

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

75
0xC0000022L

zless

Il semble dommage de zcat, car libz possède 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 zcat est équivalent à gunzip -c.

41
sourcejedi

Essayez-le avec -f ou --force:

zcat -f -- *

Puisque zcat n'est qu'un simple script qui s'exécute

exec gzip -cd "$@"

avec de longues options qui se traduiraient par

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

et, selon le man gzip (souligner le mien):

-f --force
 Forcer la compression ou la décompression même si le fichier a plusieurs liens 
 Ou le fichier correspondant existe déjà, ou si les données compressées sont 
 Lues ou écrites 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 les données d'entrée 
 Sans les modifier dans la sortie standard: laissez zcat se comporter comme un chat.

Aussi:

afin que je puisse diriger la sortie vers grep par exemple

Vous pouvez utiliser zgrep pour cela:

zgrep -- PATTERN *

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

105
don_crissti

J'utilise exactement dans le même but:

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

Il existe un remplacement direct pour ztools (zcat, zgrep, ..) appelé zutils qui unit tous les outils de décompression indépendamment du backend. Ainsi, avec la même commande, vous pouvez lire les fichiers plain, lzma, gzipped, 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'utilitaire ici ( noone.org )

7
aseques

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. Ceci tilisé pour fonctionner correctement.

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

3
Peter Laws

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

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

Et 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
1
ConcealmEnt

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

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

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

Vous pouvez ensuite rechercher quelque chose en tapant /something et frapper n pour suivant .

0
Vanni

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, 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, de sorte que vous pouvez l'utiliser très bien dans des processus supplémentaires.

  • 0
    Daniel Andersen

    En s'appuyant sur la réponse de @ Ryan, les éléments suivants obtiendront tous les fichiers "laminés" triés alphabétiquement, puis récupèrent le fichier actuel, les décompressent si nécessaire et less:

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

    ou si vous voulez les obtenir tous sous forme de flux continu, vous pouvez les tail et éventuellement les rediriger vers un autre processus

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

    Je dois noter que cela est conçu pour les journaux qui tournent quotidiennement avec la date ajoutée à la fin du fichier. Si votre journal nous enregistre dans un format différent, vous devrez modifier la première partie de l'instruction cat pour l'adapter.

    0
    cjbarth