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
.
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.
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.
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 )
Eu uso exatamente para o mesmo propósito:
{ cat /var/log/messages ; zcat /var/log/messages*.gz ; }| grep something | grep "something else" ....
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.
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
Abre comprimidos e não comprimidos, em ordem cronológica.
ls -v syslog* | tac | xargs zcat -f | less
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 .
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:
A saída está no STDOUT, para que você possa utilizá-lo muito bem em processos adicionais.
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.
Tags gzip text-processing cat