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

2

Se eu tiver alguma informação, é melhor filtrar os dados antes de executar minha ação awk ou devo fazer toda a filtragem em 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 um deles?
  • Devo usar uma ferramenta diferente?
  • Quais fatores devo considerar?
  • Como posso testar esses fatores?
por mbigras 11.04.2017 / 20:34

2 respostas

1

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

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

Com a maioria dos sistemas modernos do tipo Unix * , o bifurcação é realizado de forma bastante eficiente, mas depende do tamanho do processo iniciado, por exemplo, o lançamento perl ou python seria muito mais lento que sed ou awk .

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

Perguntas específicas

Why should I run either one?

Se você está mais familiarizado com a sintaxe de um sobre o outro, pode ser melhor para legibilidade do código (e capacidade de manutenção) para usar a ferramenta / idioma seu mais familiarizado com.

Should I use a different tool?

Neste caso específico, eu não penso assim. Ambos awk e sed são ferramentas apropriadas para este tipo de trabalho.

What factors should I be considering?

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

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

How can I test those factors?

Você pode criar perfis de versões diferentes usando o utilitário time , disponível como shell interno com o Bash, mas também como um programa executável autônomo. Por exemplo. executar os dois comandos de exemplo mostra que o primeiro exemplo levou 0,012s a mais do 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 as comparações de desempenho do perfil são afetadas pela carga do sistema e por outros fatores limitantes, portanto, é necessário repetir isso várias vezes para obter uma imagem real de qual versão é mais rápida do que a outra.

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

    
por 12.04.2017 / 11:20
1

É suficiente usar a ferramenta awk (ou sed ) para casos tão simples. Uma combinação de várias ferramentas seria supercomplicada e muitas vezes redundante:

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

A saída:

foo cats

What factors should I be considering?

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

Digamos que eu precise adicionar apenas uma palavra antes da primeira palavra na string de entrada - também é fácil com a ferramenta sed :

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

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

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

    
por 11.04.2017 / 20:57