Existe uma ferramenta que combina zcat e cat de forma transparente?

64

Ao manipular arquivos de log, alguns acabam sendo arquivos compactados com gzip graças a logrotate e outros não. Então, quando você tenta algo assim:

$ zcat *

você acaba com uma linha de comando como zcat xyz.log xyz.log.1 xyz.log.2.gz xyz.log.3.gz e depois com:

gzip: xyz.log: not in gzip format

Existe uma ferramenta que aceita os bytes mágicos, semelhante a como file funciona, e usa zcat ou cat dependendo do resultado para que eu possa enviar a saída para grep , por exemplo?

NB: Eu sei que posso fazer o script, mas estou perguntando se existe uma ferramenta lá fora.

    
por 0xC0000022L 27.05.2013 / 20:17

10 respostas

37

zless

Parece uma pena sobre zcat , pois a libz tem uma API que suporta a leitura de arquivos compactados e não compactados de forma transparente. Mas a manpage diz que zcat é equivalente a gunzip -c .

    
por 27.05.2013 / 20:24
89

Experimente com -f ou --force :

zcat -f -- *

Como zcat é apenas um script simples que é executado

exec gzip -cd "$@"

com opções longas que seriam traduzidas para

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

e, de acordo com o man gzip (enfatize o meu):

-f --force
      Force compression or decompression even if the file has multiple links
      or the corresponding file already exists, or if the compressed data is
      read from or written to a terminal. If the input data is not in a format
      recognized by gzip, and if the option --stdout is also given, copy the
      input data without change to the standard output: let zcat behave as cat.

Além disso:

so that I can pipe the output to grep for example

Você pode usar zgrep para isso:

zgrep -- PATTERN *

veja o comentário de Stéphane abaixo.

    
por 27.05.2013 / 22:05
6

Existe um substituto para ztools (zcat, zgrep, ..) chamado zutils que une todas as ferramentas de descompactação independentemente do backend. Assim, com o mesmo comando, você pode ler arquivos simples, lzma, gzipados e xz de forma transparente.

Está disponível no debian wheezy ou mais recente, provavelmente no redhat / centos também.

A página do projeto está aqui nongnu.org

Uma postagem no blog explicando o uso do utilitário aqui ( noone.org )

    
por 10.01.2014 / 09:59
6

Eu uso exatamente para o mesmo propósito:

{ cat /var/log/messages ; zcat /var/log/messages*.gz ; }| grep something | grep "something else" ....
    
por 12.04.2017 / 17:48
3

Isso funciona bem no RHEL 5.x, em que zcat é um binário. Ele falha no RHEL 6.x (e no Ubuntu 12.x), em que zcat é um script. Isso usado para funcionar bem.

Eu não usaria o zcat, mas o zgrep também não manipulará corretamente os arquivos descompactados.

    
por 27.06.2013 / 18:09
1

E o 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
    
por 10.01.2014 / 11:10
1

Abre comprimidos e não comprimidos, em ordem cronológica.

ls -v syslog* | tac | xargs zcat -f | less
    
por 23.04.2015 / 03:24
0

Copie e cole (ou coloque no final do seu arquivo ~/.bashrc ) esta função bash :

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

Agora você pode digitar, por exemplo, logs /var/log/syslog ou logs /var/log/nginx/access.log para ver all as mensagens de log syslog ou nginx da mais antiga para a mais recente com menos .

Você pode pesquisar algo digitando /something e exibindo n para seguinte .

    
por 20.08.2015 / 00:36
0

Existe um belo script perl fazendo isso. É logresolvemerge.pl do projeto awstats: link

O Logresolvemerge permite que você obtenha um arquivo de log de saída exclusivo, classificado na data, criado a partir de fontes específicas:

  • Ele pode ler vários arquivos de log de entrada
  • Pode ler arquivos de log .gz / .bz2

    A saída está no STDOUT, para que você possa utilizá-lo muito bem em processos adicionais.

        
  • por 10.05.2017 / 18:21
    0

    Com base na resposta de @ Ryan, os seguintes itens obterão todos os arquivos 'rolados' ordenados alfabeticamente, depois pegarão o arquivo atual, descompactá-los, se necessário, e less deles:

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

    ou se você quiser obtê-los todos como um fluxo contínuo, você pode tail deles e, opcionalmente, canalizar isso para outro processo

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

    Devo observar que isso é projetado para logs que são rotacionados diariamente com a data anexada ao final do arquivo. Se você registrar em um formato diferente, será necessário modificar a primeira parte da instrução cat para acomodar.

        
    por 20.09.2017 / 18:47