¿Existe alguna herramienta que combine zcat y cat de forma transparente?


71

Al manejar archivos de registro, algunos terminan como archivos comprimidos gracias a logrotateotros y no. Entonces, cuando intentas algo como esto:

$ zcat *

terminas con una línea de comando como zcat xyz.log xyz.log.1 xyz.log.2.gz xyz.log.3.gzy luego con:

gzip: xyz.log: not in gzip format

¿Existe una herramienta que tomará los bytes mágicos, similar a cómo filefunciona, y usará zcato catdependerá del resultado para que pueda canalizar la salida, greppor ejemplo?

NB: Sé que puedo escribirlo, pero estoy preguntando si ya existe una herramienta.

Respuestas:


41

zless

Parece una pena zcat, ya que libz tiene una API que admite la lectura de archivos comprimidos y no comprimidos de forma transparente. Pero la página del manual dice que zcates equivalente a gunzip -c.


Gracias por esta alternativa Podría haber pensado en eso, ¿no? ;) ... Oh bien. Detecta, +1 y acepta (también porque tienes menos representante que el otro respondedor).
0xC0000022L

Asombroso. Me ayudó mucho, estaba usando el script de shell para resolver eso durante años ... o un terrible script de perl ... fusión de resolución de registro, utilizada por awstats ... ahora conozco esta increíble herramienta. Gracias.
Luciano Andress Martini

99

Pruébalo con -fo --force:

zcat -f -- *

Dado que zcates solo un script simple que se ejecuta

exec gzip -cd "$@"

con opciones largas que se traducirían en

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

y, según el man gzip(enfatizar el mío):

-f --force
      Fuerce la compresión o descompresión incluso si el archivo tiene múltiples enlaces
      o el archivo correspondiente ya existe, o si los datos comprimidos son
      Leído o escrito en una terminal. Si los datos de entrada no están en un formato
      reconocido por gzip, y si también se da la opción --stdout, copie el
      datos de entrada sin cambios en la salida estándar: deje que zcat se comporte como cat .

También:

para poder canalizar la salida a, greppor ejemplo

Podrías usar zgreppara eso:

zgrep -- PATTERN *

aunque vea el comentario de Stéphane a continuación.


1
Gracias, esa es una alternativa interesante a la zlesssolución. Agradable y +1.
0xC0000022L

66
Tenga en cuenta que ambos zlessy zgrepson scripts que llaman gzip -cdfq(es decir zcat -fq).
Stéphane Chazelas

9

Yo uso exactamente para el mismo propósito:

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

Me gusta este enfoque porque requiere el menor tiempo dedicado a la educación de los compañeros de trabajo. Si los mensajes de registro tienen una marca de tiempo en una marca de tiempo amigable, esto es especialmente útil.
Thomas L Holaday

Excelente acercamiento. Gracias.
Miloš Đakonović

7

Hay un reemplazo directo para ztools (zcat, zgrep, ..) llamado zutils que une todas las herramientas de descompresión independientemente del backend. Entonces, con el mismo comando, puede leer archivos lzma, gzipped, xz de forma transparente.

Está disponible en debian wheezy o más reciente, probablemente también en redhat / centos.

La página del proyecto está aquí nongnu.org

Una publicación de blog que explica el uso de la utilidad aquí ( noone.org )


3

Esto funciona bien en RHEL 5.x donde zcat es un binario. Falla en RHEL 6.x (y Ubuntu 12.x) donde zcat es un script. Esto solía funcionar bien.

No estaría usando zcat en absoluto, pero zgrep tampoco manejará correctamente los archivos sin comprimir.


2

Abre tanto comprimido como no comprimido, en orden cronológico.

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

Da un orden incorrecto con más de diez archivos de registro (syslog.10.gz ...)
Vanni

Buena atrapada. -v debería arreglar eso.
Ryan

ls -rvpara evitar tac. Para los archivos de registro, less $(ls -rv syslog*)con su LESSOPENconjunto de variables de entorno funciona correctamente. Puede buscar entre archivos esc-npara encontrar la siguiente coincidencia, ignorando los límites de los archivos.
Peter Cordes

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

Esto no funciona si usted tiene su registro gire establecido para comprimir el día siguiente
cjbarth

1

¿Qué hay de la envoltura?

$ 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

Copie y pegue (o póngalo al final de su ~/.bashrcarchivo) esta función bash :

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

Ahora puede escribir, por ejemplo, logs /var/log/syslogo logs /var/log/nginx/access.logpara ver todos los mensajes de registro syslog o nginx, desde el más antiguo al más nuevo con menos .

Luego puede buscar algo escribiendo /somethingy presionando npara el siguiente .


0

Hay un hermoso script de Perl que hace exactamente esto. Es logresolvemerge.pl del proyecto awstats: http://www.awstats.org/docs/awstats_tools.html

Logresolvemerge le permite obtener un archivo de registro de salida único, ordenado por fecha, creado a partir de fuentes particulares:

  • Puede leer varios archivos de registro de entrada
  • Puede leer archivos de registro .gz / .bz2

    La salida está en STDOUT, por lo que puede utilizarla bastante bien en procesos adicionales.


  • 0

    Sobre la base de la respuesta de @ Ryan, lo siguiente obtendrá todos los archivos 'enrollados' ordenados alfabéticamente, luego obtendrá el archivo actual, descomprímalos, si es necesario, y lessellos:

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

    o si desea obtenerlos todos como una secuencia continua, puede tailhacerlo y, opcionalmente, canalizarlo a otro proceso

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

    Debo señalar que esto está diseñado para registros que se rotan diariamente con la fecha adjunta al final del archivo. Si nos registra un formato diferente, tendrá que modificar la primera parte de la catdeclaración para acomodarla.

    Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
    Licensed under cc by-sa 3.0 with attribution required.