É uma boa ideia filtrar a entrada antes de executar a ação awk?

É uma boa ideia filtrar a entrada antes de executar a ação awk?

Se eu tiver alguma entrada, é melhor filtrar os dados antes de executar minha awkação ou devo fazer toda a filtragem awk?

Por exemplo, dada a seguinte entrada:

$ echo "foo\nbar\nbaz"
foo
bar
baz

Devo correr:

$ echo "foo\nbar\nbaz" | sed 1q | awk '{ print $0 " cats" }'
foo cats

Ou:

$ echo "foo\nbar\nbaz" | awk 'NR == 1 { print $0 " cats" }'
foo cats
  • Por que devo executar qualquer um deles?
  • Devo usar uma ferramenta diferente?
  • Que fatores devo considerar?
  • Como posso testar esses fatores?

Responder1

Neste caso específico, a segunda opção é a melhor.

Em geral, é mais eficiente minimizar o número de utilidades num pipeline. É melhor não bifurcar (iniciar) processos desnecessários (como no seu primeiro exemplo com um sedprocesso desnecessário). Na Internet não é difícil encontrar exemplos de reclamações sobreusos inúteis do gato.

Com a maioria dos sistemas modernos do tipo Unix * , a bifurcação é realizada de forma bastante eficiente, mas depende do tamanho do processo que está sendo iniciado, por exemplo, iniciando perlou pythonseria muito mais lento que sedou awk.

Para comandos únicos, isso não importa muito – mas se o seu pipeline estiver dentro de um loop e sendo executado várias vezes, a remoção de processos desnecessários do seu pipeline poderá acelerar drasticamente o tempo total de execução.

Perguntas específicas

Por que devo executar qualquer um deles?

Se você estiver mais familiarizado com a sintaxe de um em vez do outro, pode ser melhor para a legibilidade (e manutenção) do código usar a ferramenta/linguagem com a qual você está mais familiarizado.

Devo usar uma ferramenta diferente?

Neste caso específico, eu não pensaria assim. Ambos awke sedsão ferramentas adequadas para este tipo de trabalho.

Que fatores devo considerar?

Se você tiver que processar vários arquivos (por exemplo, em um loop), a velocidade/eficiência seria importante.

Se você estiver processando apenas um arquivo grande, de vez em quando, a legibilidade do código poderá ser mais importante.

Como posso testar esses fatores?

Você pode criar perfis de diferentes versões usando o timeutilitário, disponível como shell integrado ao Bash – mas também como um programa executável independente. Por exemplo, executar os dois comandos de exemplo mostra que o primeiro exemplo demorou 0,012s a mais que o segundo.

$ time echo "foo\nbar\nbaz" | sed 1q | awk '{ print $0 " cats" }'
foo\nbar\nbaz cats

real    0m0.056s
user    0m0.000s
sys     0m0.045s

$ time echo "foo\nbar\nbaz" | awk 'NR == 1 { print $0 " cats" }'
foo\nbar\nbaz cats

real    0m0.044s
user    0m0.000s
sys     0m0.031s

Observe que os benchmarks de criação de perfil são afetados pela carga do sistema e outros fatores limitantes, portanto, você precisará repetir isso um grande número de vezes para obter uma imagem real de qual versão é mais rápida que a outra.


* Com MS Windows, bifurcaçãoémais caro, portanto, minimizar o número de processos iniciados faz diferença ao executar em ambientes como o Cygwin.

Responder2

É o suficiente para usarestranho(oused) ferramenta para casos tão simples. Uma combinação de múltiplas ferramentas seria muito complicada e muitas vezes redundante:

echo -e "foo\nbar\nbaz" | awk 'NR==1{print $0" cats"}'

A saída:

foo cats

Que fatores devo considerar?

Certifique-se de que o processamento de texto necessário requer a combinação de várias ferramentas diferentes; caso contrário, use o poder de uma ferramenta distinta

Digamos que se eu precisar apenas adicionar uma determinada palavra antes da primeira palavra na string de entrada - também é fácil comsedferramenta:

echo -e "foo\nbar\nbaz" | sed 's/^.*$/& cats/; 1q'
foo cats

echo -e, esinalizador "permite a interpretação de escapes de barra invertida"


De qualquer forma, depende de quão complexo é o seu texto de entrada e quão sofisticadas são as suas regras de processamento de texto

informação relacionada