De acordo com o manual do awk, BEGIN e END não são usados para combinar a entrada, mas sim para fornecer inicialização e limpeza -up informações para o script awk. Aqui está o exemplo dado:
ls -l | \ awk "BEGIN { print "Files found:\n" } /\<[a|x].*\.conf$/ { print $9 }" Files found: amd.conf antivir.conf xcdroast.conf xinetd.conf
Primeiro, isso imprime uma string para a saída. Em seguida, ele verifica a entrada para uma correspondência de padrão, onde a entrada começa com a ou x seguido por qualquer caractere uma ou várias vezes seguido pelo .conf. Para quaisquer correspondências, a 9ª coluna é impressa.
O fato de sermos forçados a usar begin aqui, isso significa que awk só pode usar no máximo uma função de impressão que contenha BEGIN ou END? Se não, por que não podemos simplesmente usar a função de impressão no início sem a palavra-chave BEGIN? Parece que BEGIN é supérfluo.
Comentários
- Simplesmente executar o comando sem o BEGIN responderia à sua pergunta, mostrando que ' não é supérfluo e que você obteria um resultado diferente.
Resposta
O BEGIN
não é “t supérfluo. Se você não especificar BEGIN
, então print
será executado para cada linha de entrada.
Citando de o manual :
A
BEGIN
regra é executada apenas uma vez, antes que o primeiro registro de entrada seja lido. Da mesma forma, umaEND
regra é executada apenas uma vez, depois que toda a entrada é lida.
$ seq 5 | awk "BEGIN{print "Hello"}/4/{print}" # Hello printed once Hello 4 $ seq 5 | awk "{print "Hello"}/4/{print}" # Hello printed for each line of input Hello Hello Hello Hello 4 Hello $
Resposta
awk
processa cada linha de entrada para as expressões fornecidas no corpo diferente de BEGIN
e END
blocos. No caso de BEGIN
e END
blocos, awk
irá processar as instruções apenas uma vez, antes de o processamento da entrada começar e após o processamento da entrada ter sido concluído, resp ectivamente. Sem o bloco BEGIN
, não só você não seria capaz de imprimir informações únicas, como cabeçalhos, como também não seria capaz de inicializar com eficiência algumas das variáveis exigidas pelo corpo. Além disso, para sua informação, um programa awk
pode ter vários blocos BEGIN
e END
.
Resposta
awk
executa cada bloco apenas quando o padrão antes dele corresponder. O padrão vazio (apenas bloco) corresponde a todas as linhas. BEGIN
e END
são padrões especiais que correspondem ao início e ao final do arquivo (análogo ao significado de ^
e $
na direção horizontal).
Se você quiser que algo seja executado antes de ler o arquivo, use BEGIN
. Por exemplo, inicialização de contadores ou algo assim. END
poderia então coletar os resultados.
Resposta
No exemplo dado, que eu acho simplificado para maior clareza pedagógica, você tem razão ao dizer que é supérfluo. Você poderia obter os mesmos resultados sem usar BEGIN
.
1 == NR { print "Files found:\n" } /\<[a|x].*\.conf$/ { print $9 }
produziria os mesmos resultados, pois a instrução de impressão é restrito apenas à primeira linha de entrada.
Dito isso, os blocos BEGIN
e END
são incrivelmente poderosos Ferramentas. Como outras soluções mencionaram, você pode usar o bloco BEGIN
para inicializar variáveis ou outras rotinas que só precisam ser executadas uma vez, mas também pode ser usado para executar comandos Awk quando não houver arquivos para processar. Um exemplo simples:
BEGIN { print sqrt(12/4) }
Você pode ver um exemplo mais sério de programação no Awk sem processar qualquer entrada aqui .
Da mesma forma, o bloco END
é extremamente útil para realizar cálculos e resumir todas as entradas. Isso não pode ser feito (normalmente) sem primeiro ler todos os dados. Um exemplo simples de resumir a entrada pode ser encontrado aqui