Pesquisa de site

Aprenda como usar os padrões especiais do Awk ‘BEGIN and END’ – Parte 9


Na Parte 8 desta série do Awk, introduzimos alguns recursos poderosos de comando do Awk, ou seja, variáveis, expressões numéricas e operadores de atribuição.

À medida que avançamos, neste segmento, cobriremos mais recursos do Awk, e esses são os padrões especiais: BEGIN e END.

Esses recursos especiais serão úteis à medida que tentamos expandir e explorar mais métodos de construção de operações Awk complexas.

Para começar, vamos voltar nossos pensamentos para a introdução da série Awk, lembre-se que quando iniciamos esta série, eu indiquei que a sintaxe geral de um Awk é executado > comando é:

awk 'script' filenames  

E na sintaxe acima, o script Awk tem o formato:

/pattern/ { actions } 

Quando você considera o padrão no script, normalmente é uma expressão regular; além disso, você também pode pensar no padrão como padrões especiais BEGIN e END. Portanto, também podemos escrever um comando Awk no formato abaixo:

awk '
 	BEGIN { actions } 
 	/pattern/ { actions }
 	/pattern/ { actions }
            ……….
	 END { actions } 
' filenames  

Caso você use os padrões especiais: BEGIN e END em um script Awk, isto é o que cada um deles significa:

  1. Padrão BEGIN: significa que o Awk executará as ações especificadas em BEGIN uma vez antes de qualquer linha de entrada ser lida.
  2. Padrão END: significa que o Awk executará as ações especificadas em END antes de realmente sair.

E o fluxo de execução de um script de comando Awk que contém esses padrões especiais é o seguinte:

  1. Quando o padrão BEGIN é usado em um script, todas as ações para BEGIN são executadas uma vez antes de qualquer linha de entrada ser lida.
  2. Em seguida, uma linha de entrada é lida e analisada nos diferentes campos.
  3. Em seguida, cada um dos padrões não especiais especificados é comparado com a linha de entrada para uma correspondência. Quando uma correspondência é encontrada, as ações para esse padrão são então executadas. Esta etapa será repetida para todos os padrões que você especificou.
  4. A seguir, os estágios 2 e 3 são repetidos para todas as linhas de entrada.
  5. Quando todas as linhas de entrada forem lidas e tratadas, caso você especifique o padrão END, a(s) ação(ões) serão executadas.

Você deve sempre se lembrar desta sequência de execução ao trabalhar com padrões especiais para obter os melhores resultados em uma operação Awk.

Para entender tudo, vamos ilustrar usando o exemplo da parte 8, sobre a lista de domínios de propriedade da Tecmint, armazenada em um arquivo chamado domains.txt.

news.linux-console.net
linux-console.net
linuxsay.com
windows.linux-console.net
linux-console.net
news.linux-console.net
linux-console.net
linuxsay.com
linux-console.net
news.linux-console.net
linux-console.net
linuxsay.com
windows.linux-console.net
linux-console.net
cat ~/domains.txt

Neste exemplo, queremos contar quantas vezes o domínio linux-console.net está listado no arquivo domains.txt. Então escrevemos um pequeno script shell para nos ajudar a fazer isso usando a ideia de variáveis, expressões numéricas e operadores de atribuição que tem o seguinte conteúdo:

#!/bin/bash
for file in $@; do
        if [ -f $file ] ; then
                #print out filename
                echo "File is: $file"
                #print a number incrementally for every line containing linux-console.net 
                awk '/^linux-console.net/ { counter+=1 ; printf "%s\n", counter ; }' $file
        else
                #print error info incase input is not a file
                echo "$file is not a file, please specify a file." >&2 && exit 1
        fi
done
#terminate script with exit code 0 in case of successful execution 
exit 0

Vamos agora empregar os dois padrões especiais: BEGIN e END no comando Awk no script acima como segue:

Vamos alterar o script:

awk '/^linux-console.net/ { counter+=1 ; printf "%s\n", counter ; }' $file

Para :

awk ' BEGIN {  print "The number of times linux-console.net appears in the file is:" ; }
                      /^linux-console.net/ {  counter+=1  ;  }
                      END {  printf "%s\n",  counter  ; } 
                    '  $file

Depois de fazer as alterações no comando Awk, o script de shell completo agora se parece com isto:

#!/bin/bash
for file in $@; do
        if [ -f $file ] ; then
                #print out filename
                echo "File is: $file"
                #print the total number of times linux-console.net appears in the file
                awk ' BEGIN {  print "The number of times linux-console.net appears in the file is:" ; }
                      /^linux-console.net/ {  counter+=1  ;  }
                      END {  printf "%s\n",  counter  ; } 
                    '  $file
        else
                #print error info incase input is not a file
                echo "$file is not a file, please specify a file." >&2 && exit 1
        fi
done
#terminate script with exit code 0 in case of successful execution 
exit 0

Quando executamos o script acima, ele primeiro imprimirá a localização do arquivo domains.txt, depois será executado o script de comando Awk, onde o BEGIN padrão especial nos ajuda a imprimir a mensagem “O número de vezes que linux-console.net aparece no arquivo é: ” antes que qualquer linha de entrada seja lida no arquivo.

Então nosso padrão, /^linux-console.net/ é comparado com cada linha de entrada e a ação, { counter+=1 ; } é executado para cada linha de entrada, que conta o número de vezes que linux-console.net aparece no arquivo.

Por fim, o padrão END imprimirá o total de vezes que o domínio linux-console.net aparece no arquivo.

./script.sh ~/domains.txt 

Para concluir, examinamos mais recursos do Awk explorando os conceitos de padrão especial: BEGIN e END.

Como mencionei antes, esses recursos do Awk nos ajudarão a construir operações de filtragem de texto mais complexas, há mais para abordar nos recursos do Awk e na parte 10, abordaremos o idéia das variáveis integradas do Awk, então fique conectado.

Artigos relacionados: