Usando grep vs awk

17

Para capturar um padrão específico awke greppode ser usado. Por que devemos usar um sobre o outro? Qual é mais rápido e por quê?

Se eu tivesse um arquivo de log e desejasse pegar um determinado padrão, poderia executar um dos seguintes

awk '/pattern/' /var/log/messages

ou

grep 'pattern' /var/log/messages

Eu não fiz nenhum benchmarking, então não saberia. Alguém pode elaborar isso? É ótimo conhecer o funcionamento interno dessas duas ferramentas.

holasz
fonte
Preceda qualquer comando, mesmo os scripts de shell, com o timetempo necessário para executar o comando. Ex: time ls -l.
quer

Respostas:

26

O grep provavelmente será mais rápido:

# time awk '/USAGE/' imapd.log.1 | wc -l
73832

real    0m2.756s
user    0m2.740s
sys     0m0.020s

# time grep 'USAGE' imapd.log.1 | wc -l
73832

real    0m0.110s
user    0m0.100s
sys     0m0.030s

awk é uma linguagem de programação interpretada, na qual grep é um programa de código c compilado (que é otimizado adicionalmente para encontrar padrões em arquivos).

(Observação - executei os dois comandos duas vezes para que o cache não distorçasse os resultados)

Mais detalhes sobre idiomas interpretados na wikipedia.

Como Stephane apontou corretamente nos comentários, sua milhagem pode variar devido à implementação do grep e awk que você usa, do sistema operacional em que está instalado e do conjunto de caracteres que você está processando.

Drav Sloan
fonte
2
Sem dizer qual implementação grep ou awk você está usando, qual arquitetura de computador e com qual conjunto de caracteres do sistema, esses tempos têm pouco valor.
Stéphane Chazelas
1
o segundo comando também usará a versão recém-armazenada em cache. Não duvido que o grep seja mais rápido, mas não tanto quanto seus números mostram.
Exussum 28/08/13
(portanto, executando awk, grep, awk, grep e postando os resultados do segundo conjunto de awk e grep :) e FYI, moro em um local UTF8.
Drav Sloan
1
Curiosamente, com as ferramentas BSD (em um Mac), o awk (31.74s) é um pouco mais rápido que o sed (33.34s), que é um pouco mais rápido que o grep (34.21s). O gnu awk é o proprietário de todos eles em 5.24s, não tenho gnu grep ou sed para testar.
28413 Kevin
1
grep deve ser um pouco mais rápido, porque o awk faz mais com cada linha de entrada do que apenas procurar um regexp nele, por exemplo, se um campo for referenciado no script (o que não é o caso), o awk dividirá cada linha de entrada em campos com base no separador de campo e preenche variáveis ​​internas. mas com o que você postou, quase não deve haver diferença. De longe, a diferença mais importante entre os regexps de correspondência grep e awk wrt é que o grep pesquisa uma linha correspondente em toda a linha, enquanto o awk pode pesquisar campos específicos e, assim, fornecer mais precisão e menos correspondências falsas.
Ed Edison19
14

Use a ferramenta mais específica e expressiva. A ferramenta que melhor se adapta ao seu caso de uso provavelmente será a mais rápida.

Como um guia aproximado:

  • procurando linhas que correspondam a uma substring ou regexp? Use grep.
  • selecionando determinadas colunas de um arquivo simplesmente delimitado? Use corte.
  • executando substituições baseadas em padrões ou ... outras coisas que o sed pode razoavelmente fazer? Use sed.
  • precisa de alguma combinação dos 3 acima, formatação printf ou loops e ramificações de uso geral? Use awk.
Sem utilidade
fonte
+1, exceto usar em perlvez de awk. se você precisa de algo mais complicado do que o grep / cortar / sed, então as chances são awk não será suficiente e você precisa de algo "full-blown"
sds
@sds porque não python?
RetroCode 23/09/16
@RetroCode: python é mais "de uso geral" que perl; o one-liner equivalente provavelmente será muito mais longo.
sds
3
@ sds não, você não precisa de perl, a menos que faça algo diferente do processamento de texto. O awk é adequado para o processamento de texto mais complicado que o grep / cut / sed e, como bônus, é padrão em todas as instalações do UNIX, diferentemente do perl.
Ed Morton
10

Ao pesquisar apenas por seqüências de caracteres e velocidade, você quase sempre deve usar grep. São ordens de magnitude mais rápidas do que awkquando se trata apenas de pesquisas brutas.

fonte As diferenças de funcionamento e desempenho de sed, awk e outras utilidades ao analisar Unix

UTILITY    OPERATION TYPE      EXECUTION TIME     CHARACTERS PROCESSED PER SECOND
                               (10 ITERATIONS)
-------    --------------      ---------------    -------------------------------
grep       search only         41 sec.            489.3 million
sed        search & replace    4 min. 4 sec.      82.1 million
awk        search & replace    4 min. 46 sec.     69.8 million
Python     search & replace    4 min. 50 sec.     69.0 million
PHP        search & replace    15 min. 44 sec.    21.2 million
slm
fonte
1
Obrigado por esta boa visão geral de todos esses programas. Realmente lança luz na escuridão.
holasz
1
~ headtilt ~ PHP está lá, mas Perl não está?
precisa saber é o seguinte
@ Izkata - Eu pensei a mesma coisa quando vi esta mesa há um tempo atrás.
slm
1
Não é realmente justo para os outros utilitários que o grep esteja apenas pesquisando e eles também estejam substituindo.
Kevin
1
Esses são números completamente falsos. Fale sobre a comparação de maçãs e laranjas - é como dizer que você pode encontrar um carro novo no site A em 5 segundos, enquanto você pode encontrar um carro, negociar um preço, obter um empréstimo e comprar o carro no site B em 1 hora. portanto, o site A é mais rápido que o site B. O artigo que você citou está completamente errado nas declarações de velocidade relativa de execução entre grep, sed e awk e também diz awk ... has PCRE matching for regular expressionsque é completamente falso.
Ed Morton
5

Embora eu concorde que, em teoria, grepdeve ser mais rápido do queawk , na prática, o YMMV, pois isso depende muito da implementação que você usa.

aqui comparando grep e awk do busybox 1.20.0, GNU grep 2.14, mawk 1.3.3, GNU awk 4.0.1 no Debian / Linux 7.0 amd64 (com glibc 2.17) em um local UTF-8 em um arquivo UTF-8 em um arquivo de 240 MB de 2,5 milhões de linhas de Caracteres somente ASCII.

$ time busybox grep error error | wc -l
331003
busybox grep error error  8.31s user 0.12s system 99% cpu 8.450 total
wc -l  0.07s user 0.11s system 2% cpu 8.448 total
$ time  busybox awk /error/ error | wc -l
331003
busybox awk /error/ error  2.39s user 0.84s system 98% cpu 3.265 total
wc -l  0.12s user 1.23s system 41% cpu 3.264 total
$ time  grep error error | wc -l
331003
grep error error  0.80s user 0.10s system 99% cpu 0.914 total
wc -l  0.00s user 0.11s system 12% cpu 0.913 total
$ time mawk /error/ error | wc -l
330803
mawk /error/ error  0.54s user 0.13s system 91% cpu 0.732 total
wc -l  0.03s user 0.08s system 14% cpu 0.731 total
$ time gawk /error/ error | wc -l
331003
gawk /error/ error  1.37s user 0.12s system 99% cpu 1.494 total
wc -l  0.04s user 0.07s system 7% cpu 1.492 total
$ time 

No código C, apenas o GNU grep recebe um impulso significativo e se torna mais rápido que mawk.

O conjunto de dados, o tipo de regexp também pode fazer uma grande diferença. Para regexps, awkdeve ser comparado com grep -Ecomo awkregexps 's são REs prolongados.

Para esse conjunto de dados, awkpode ser mais rápido do que grepem sistemas baseados em busybox ou sistemas onde mawké o padrão awke o código do idioma padrão é baseado em UTF-8 (IIRC, costumava ser o caso no Ubuntu).

Stéphane Chazelas
fonte
2

Em poucas palavras, grepfaz uma coisa apenas como muitas outras ferramentas UNIX e combina uma linha com o padrão fornecido, e faz bem. Por outro lado,awk é uma ferramenta mais sofisticada, pois é uma linguagem de programação completa definida pelo padrão POSIX com recursos típicos como variáveis, matrizes, expressões, funções ou instruções de controle para varredura e processamento de padrões.

Na minha opinião, depende da implementação do desempenho de ambas as ferramentas em caso de correspondência de padrões e do tamanho de alguma entrada que você deseja processar. Eu esperaria que o grep seja geralmente mais eficiente que o awk, pois combina apenas. Mas você não pode escrever com grep um código simples para executar tarefas mais complexas, como processamento adicional de registros correspondentes, computação ou impressão de resultados sem usar outras ferramentas.

dsmsk80
fonte