Estou usando um script para baixar regularmente minhas mensagens do Gmail que compactam o arquivo .eml bruto em arquivos .gz. O script cria uma pasta para cada dia e, em seguida, compacta todas as mensagens em seu próprio arquivo.
Eu gostaria de uma maneira de pesquisar neste arquivo por uma "string".
Grep sozinho não parece fazê-lo. Eu também tentei o SearchMonkey.
zgrep
:zgrep - search possibly compressed files for a regular expression
Respostas:
Se você deseja grep recursivamente em todos os arquivos .eml.gz no diretório atual, você pode usar:
Você precisa escapar do primeiro
*
para que o shell não o interprete.-print0
diz ao find para imprimir um caractere nulo após cada arquivo encontrado;xargs -0
lê da entrada padrão e executa o comando após cada arquivo;zgrep
funciona comogrep
, mas descompacta o arquivo primeiro.fonte
zgrep
na verdade, parece mais rápido do quegrep
executado em arquivos não compactados. Deve ser porque os arquivos compactados podem ser lidos no HD e descompactados mais rapidamente do que ler um arquivo não compactado do HD.xargs
usa espaços em branco (espaço em branco) por padrão. Certamente, os arquivos quase nunca têm novas linhas, mas os espaços não são desconhecidos (mesmo que a maioria dos tipos UNIXy os desaproveite). Dito isso, você pode simplificar sem se preocupar com o espaço em branco de maneira ainda mais fácil:find . -name '*.eml.gz' -exec zgrep "STRING" {} +
isso gera os mesmos argumentos por lançamentoxargs
, a segurança de-print0
/-0
e tudo sem a sobrecarga de um processo e inicialização de processo extras e de maneira bastante concisa.-exec
com o+
POSIX especificado, portanto, ele deve estar na maioria dos sistemas semi-recentes do tipo UNIX, que eu saiba.ABCLog04_18_18_2_21.gz
Existe uma maneira de procurar recursivamente arquivos começando com ABC *. Eu tentei substituir\*.eml.gz
no seu exemplo acima porABCLog*
e obter um erro sobre o formato do arquivo .: #find: paths must precede expression: ABCLog-2018-03-12-10-16-1.log.gz Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
Há muita confusão aqui, porque não há apenas uma
zgrep
. Eu tenho duas versões no meu sistema,zgrep
degzip
ezgrep
parazutils
. O primeiro é apenas um script de invólucro que chamagzip -cdfq
. Não suporta o-r, --recursive
switch. 1O último é um
c++
programa e suporta a-r, --recursive
opção.A execução
zgrep --version | head -n 1
revelará qual deles (se houver) é o padrão:é o script do wrapper,
é o
cpp
executável.Se você tiver o último, poderá executar:
De qualquer forma, como sugerido, o
find
+zgrep
funcionará igualmente bem com qualquer uma das versões dezgrep
:Se
zgrep
estiver ausente do seu sistema (altamente improvável), você pode tentar:mas há uma grande desvantagem: você não saberá onde estão as correspondências, pois não há um nome de arquivo anexado às linhas correspondentes.
1: porque seria problemático
fonte
zgrep
zutils não estiver disponível, você poderá instalá-lo no Ubuntu comsudo apt-get install zutils
.grep -n
,zgrep -n
imprimirá a linha no.s. Ele está no manual ... #ag
é uma variante dogrep
, com alguns recursos extras agradáveis.Assim:
Se não estiver instalado,
fonte
ag: truncated file: Success
como resultado. Qualquer outra bandeira devo adicionar?A recursão sozinha é fácil:
No entanto, para arquivos compactados, você precisa de algo como:
path/to/directory
deve ser o diretório pai que contém os subdiretórios para cada dia.zgrep
é a resposta óbvia, mas, infelizmente, não suporta a-r
bandeira. Deman zgrep
:fonte
Se o seu sistema possui o zgrep, você pode simplesmente
zgrep -irs your-pattern-goes-here the-folder-to-search-goes-here/
Se o seu sistema não possui zgrep, você pode usar o comando find para executar o zcat e o grep em cada arquivo da seguinte maneira:
find the-folder-to-search-goes-here/ -name '*.gz' \ -exec sh -c 'echo "Searching {}" ; zcat "{}" | grep your-pattern-goes-here ' \;
fonte
Searching ~/gmvault-db/db/2015-02/03/whatever.gz
zgrep
não levará a-r
bandeira por algum motivo. Isso é mencionadoman zgrep
(veja também minha resposta).xzgrep é um derivado dos utilitários do zgrep (menos / bin / xzgrep)
Na página Man:
-l imprime o nome do arquivo correspondente
-R para recursão não funcionará, pois é especificamente proibido no script, no entanto, simples globbing de shell deve nos levar até lá
a partir de um caminho relativo em que ./today/sample.eml.gz, corresponda em todas as instâncias desse nível um abaixo da nossa posição relativa no shell, que termina com ".eml.gz"
fonte