Differences

This shows you the differences between two versions of the page.

Link to this comparison view

o_awk_pt_br [2017/09/05 12:18] (current)
Line 1: Line 1:
 +====== Introdução ======
  
 +
 +Awk é uma linguagem procedural (ou imperativa) interpretada. As suas vantagens em relação a C ou Pascal são: 
 +  - se for necessário fazer frequentemente alterações em vários arquivos texto, onde quer que seja que certos padrões apareçam; ​
 +  - se for necessário extrair dados de algumas linhas de um arquivo enquanto o resto é descartado. ​
 +
 +Ou seja, com awk é possível gerenciar tarefas simples de "​reformatar dados" com apenas algumas linhas de código.
 +
 +Com awk é possível: gerenciar pequenos banco de dados pessoais; gerar relatórios;​ validar dados; produzir índices, e fazer outras tarefas de preparação de documentos; fazer experimentos com algoritmos que podem ser adaptados posteriormente a outras linguagens de programação.
 +
 +Função básica do **awk** é procurar por linhas (ou outras unidades de texto) em arquivos que possuem certos padrões especificados no programa; para cada **padrão** (pattern) deve haver uma ação associada, isto é, quando uma linha corresponde a um dos padrões, awk realiza a ação especificada naquela linha; depois, awk continua processando as linhas de entrada desta maneira até encontrar o fim do arquivo de entrada; o conjunto de comandos **padrão-ação** pode aparecer literalmente como um programa ou em um arquivo específico com a opção **-f**; arquivos de entrada são lidos em ordem; se não há arquivos, a entrada padrão é lida.
 +
 +Programas em awk são diferentes dos programas na maioria das outras linguagens porque são data-driven,​ isto é, deve-se descrever os dados com os quais se quer trabalhar, e o que fazer quando encontrá-los. Em outras linguagens procedurais normalmente é mais difícil descrever claramente os dados que o programa irá processar. Por isso, programas awk são mais fáceis de escrever e ler.
 +
 +Quando awk é executado, deve-se especificar um programa awk que diga o que ele tem que fazer. O programa consiste numa série de regras, sendo que cada uma especifica um padrão que deve ser procurado e uma ação que deve ser tomada quando o padrão é encontrado. Sintaticamente,​ uma regra consiste de um padrão seguido de uma ação que deve estar entre { e }. Cada regra é separada por uma nova linha. Então, um programa awk se parece com: 
 +<sxh bash>
 +<​padrão>​ { <​ação>​ } 
 +<​padrão>​ { <​ação>​ } 
 +...
 +</​sxh>​
 +
 +====== Executando um Programa awk ======
 +
 +Existem várias maneiras de executar um programa awk.
 +
 +1) Se o programa é pequeno, é mais fácil incluí-lo no comando de execução. Por exemplo: ​
 +<sxh bash>
 +awk '<​Programa>'​ <​Arq1Entrada>​ <​Arq2Entrada>​ ... 
 +</​sxh>​
 +
 +<​nowiki><​programa></​nowiki>​ consiste numa série de padrões e ações. Este comando é usado quando programas simples são escritos no momento que se deseja utilizá-los. Este formato de comando instrui o shell, ou interpretador de comandos, para iniciar o awk e usar o programa para processar registros nos arquivos de entrada. As aspas simples em torno do programa instruem o shell para: não interpretar os caracteres awk como caracteres especiais do shell; e tratar todo o programa como um único argumento para awk e permitir que o programa tenha mais do que uma linha.
 +
 +Também é possível executar o awk sem arquivos de entrada. Neste caso, quando se digita a linha de comando: ​
 +<sxh bash>
 +awk '<​programa>​ ' ​
 +</​sxh>​
 +
 +O awk aplica o programa à entrada padrão, o que significa que tudo que for digitado no terminal até que seja pressionado CTRL+d. O exemplo a seguir copia os caracteres digitados para a saída padrão. ​
 +<sxh bash>
 +awk '{ print }' ​
 +Este eh um exemplo ​
 +Este eh um exemplo ​
 +da utilizacao do awk! 
 +da utilizacao do awk! 
 +Fim! 
 +Fim! 
 +</​sxh>​
 +
 +2) Quando o programa é extenso, é mais conveniente colocá-lo em um arquivo e executá-lo da seguinte maneira: ​
 +<sxh bash>
 +awk -f <​ArqPrograma>​ <​Arq1Entrada>​ <​Arq2Entrada>​ ... 
 +</​sxh>​
 +
 +**-f** <​ArqPrograma>​ intrui o awk a pegar o programa do arquivo. Qualquer nome pode ser usado no arquivo. Por exemplo, é possível colocar o programa: ​
 +<sxh bash>
 +BEGIN { print "Hello World!"​ } 
 +</​sxh>​
 +No arquivo "​exemplo"​. O comando para execução é: 
 +<sxh bash>
 +awk -f exemplo ​
 +</​sxh>​
 +
 +Se não fosse utilizado um arquivo, o comando para execução seria: ​
 +<sxh bash>
 +awk "BEGIN { print \"​Hello World! \" }" ​
 +</​sxh>​
 +
 +A contra-barra (\) é necessária antes de cada aspas (") interna devido às regras do shell.
 +
 +Considerando programas executáveis,​ é possível escrever scripts em awk usando #!, que funciona em Linux e Unix derivados do Berkeley Unix, System V Release 4 ou 3. Este mecanismo não funciona com sistemas mais antigos. Por exemplo, o arquivo "​exemplo"​ apresentado anteriormente pode ser alterado da seguinte maneira: ​
 +<sxh bash>
 +#! /bin/awk -f 
 +BEGIN { print "Hello World!"​ } 
 +</​sxh>​
 +
 +Depois, basta transformá-lo em um executável usando o comando chmod e chamá-lo a partir do prompt. ​
 +<sxh bash>
 +chmod +x exemplo ​
 +</​sxh>​
 +
 +Agora vamos mandar executar o nosso script
 +<sxh bash>
 +exemplo ​
 +Hello World 
 +</​sxh>​
 +
 +Isto é equivalente a usar o comando **awk -f** exemplo. A linha que começa com #! contém o caminho e o nome do interpretador que deve ser executado, e também comandos de inicialização opcionais que podem ser passados para o interpretador. O sistema operacional então executa o interpretador com os parâmetros fornecidos.
 +
 +====== Comentários ======
 +
 +Na linguagem awk, um comentário começa com o caracter #, e continua até o final da linha. O caracter # não precisa ser o primeiro caracter da linha. O arquivo exemplo pode ser alterado para inserir um comentário da seguinte maneira: ​
 +<sxh bash>
 +# Primeiro programa escrito na LP awk 
 +# Este programa apenas exibe uma mensagem na tela 
 +BEGIN { print "Hello World!"​ }
 +</​sxh>​
 +
 +====== Exemplos ======
 +
 +1) Exemplo simples ​
 +<sxh bash>
 +awk '/​root/​ { print $0 }' /etc/passwd
 +</​sxh>​
 +
 +Este comando executa um programa awk simples que procura pela string "​root"​ no arquivo de entrada "/​etc/​passwd"​. Quando uma linha que contém "​root"​ é encontrada, ela é exibida na tela do computador, pois print $0, ou simplesmente print, significa imprimir a linha corrente. A / que aparece antes e depois de root indicam que root é o padrão a ser procurado. As aspas simples ao redor do programa notifica o shell para não interpretar os caracteres como caracteres especiais do shell. ​
 +Este programa também poderia ser escrito em um arquivo, como por exemplo: ​
 +<sxh bash>
 +vim procura.awk
 +#! /bin/awk -f 
 +BEGIN { 
 +  print "​Ocorrencias:​ " ​
 +
 +#Padrão procurado
 +/root/ { print }
 +</​sxh>​
 +
 +Agora vamos dar permissão para o nosso arquivo
 +<sxh bash>
 +chmod +x procura.awk
 +</​sxh>​
 +
 +Neste caso a execução seria: ​
 +<sxh bash>
 +procura.awk /etc/passwd
 +</​sxh>​
 +
 +Numa regra awk tanto o padrão como a ação podem ser omitidos, mas não ambos. Se o padrão é omitido, então a ação é executada para cada linha de entrada. Se a ação é omitida, a ação default é imprimir todas as linhas que correspondam ao padrão. Então, é possível eliminar a ação (o comando print) neste exemplo e o resultado seria o mesmo. Por exemplo: ​
 +<sxh bash>
 +awk '/​root/'​ /etc/passwd
 +</​sxh>​
 +Porém, omitir o comando print e manter {}, faz com que uma ação "​vazia"​ seja definida, isto é, nada é realizado. Por exemplo: ​
 +<sxh bash>
 +awk '/awk/ { }' texto.txt
 +</​sxh>​
 +
 +2) Exemplo com duas regras ​
 +O interpretador awk lê os arquivos de entrada linha a linha, e para cada uma ele testa o padrão especificado na(s) regra(s). Se vários padrões são encontrados,​ então várias ações são executadas na ordem em que aparecem no programa awk. Se nenhum padrão é encontrado, nenhuma ação é executada. Por exemplo, o seguinte programa awk contém duas regras: ​
 +<sxh bash>
 +awk '/0/ {print $1} /40/ {print $1}' /etc/passwd /etc/fstab
 +</​sxh>​
 +
 +A primeira regra possui a string 0 como padrão e print $1 como ação. A segunda regra tem a string 40 como padrão e também print $1 como ação. As ações sempre devem estar entre { e }. O programa exibe cada linha que contém a string 0 ou 40. Se uma linha contém as duas strings, ela é exibida duas vezes, uma para cada regra.
 +
 +====== Comandos X Linhas ======
 +
 +Geralmente cada linha em um programa awk é um "​separador"​ de comandos ou de regras, como por exemplo: ​
 +<sxh bash>
 +awk '/​root/​ { print } 
 +>  /daemon/ { print }' /etc/passwd
 +</​sxh>​
 +
 +Entretanto, awk irá ignorar novas linhas depois de um dos seguintes caracteres: , { ? : <​nowiki>​||</​nowiki>​ && do else 
 +Uma nova linha em qualquer outro ponto é considerada o final de um comando. ​
 +
 +Se o programador quiser "​dividir"​ um único comando em duas linhas, basta colocar o caracter \ no final da primeira linha. Este caracter no final da linha indica que o comando continua, e pode ser usado em qualquer parte de um comando, até no meio de uma string ou expressão. Por exemplo: ​
 +<sxh bash>
 +awk '/Esta expressao eh muito extensa, por isso continua\ ​
 +                  na proxima linha/ { print } ' ​
 +</​sxh>​
 +
 +awk é uma linguagem "​orientada a linha"​. Cada ação de uma regra deve começar na mesma linha do padrão. Para ter o padrão e a ação em linhas separadas, deve-se usar \. 
 +Torna-se importante salientar que, além do uso deste caracter para "​divisão"​ de um comando só ser permitido em arquivos de programas, ele não é aceito em todas as versões de awk. 
 +
 +Quando os comandos awk são "​pequenos",​ pode-se colocar mais do que um em uma única linha separados por ;. Por exemplo: ​
 +<sxh bash>
 +awk '/​root/​ { print };/daemon/ { print }' /etc/passwd
 +</​sxh>​
 +
 +====== Exemplos de Programas de uma Linha ======
 +
 +Muitos programas awk úteis possuem apenas uma ou duas linhas.
 +
 +1) Programa que imprime o tamanho da maior linha. ​
 +<sxh bash>
 +awk '{ if (length($0) > max) max=length($0) } 
 + END { print max }' /etc/passwd
 +</​sxh>​
 +
 +2) Programa que imprime todas as linhas que possuem mais do que 80 caracteres. A única regra possui uma expressão relacional e seu padrão, e não possui ação. Portanto, a ação default, imprimir o registro, é tomada. ​
 +<sxh bash>
 +awk '​length($0) > 80' /​etc/​inittab
 +</​sxh>​
 +
 +3) Este programa imprime cada linha que possui pelo menos um campo. Esta é uma maneira simples de eliminar linhas em branco de um arquivo. ​
 +<sxh bash>
 +awk '​NF>​0'​ /etc/fstab
 +</​sxh>​
 +
 +4) Este programa imprime sete números randômicos de 0 a 100, inclusive. ​
 +<sxh bash>
 +awk 'BEGIN { for(i=1; i<=7; i++) 
 + print int(101*rand()) }'
 +</​sxh>​
 +
 +5) Este programa imprime o número total de bytes usados pelos <​arquivos>​. ​
 +<sxh bash>
 +ls -lg /etc | awk '{x+= $4}; END {print "total bytes:"​ x}'
 +</​sxh>​
 +
 +6) Este programa conta o número de linhas em um arquivo ​
 +<sxh bash>
 +awk 'END { print NR }' /etc/group
 +</​sxh>​
 +
 +====== Expressões Regulares ======
 +
 +Uma expressão regular é uma maneira de descrever um conjunto de strings. A expressão regular mais simples é uma seqüência de letras, números, ou ambos.
 +
 +Uma expressão regular pode ser usada como um padrão quando colocada entre /. Neste caso ela é comparada com cada registro em todo o texto. Normalmente só é necessário encontrar uma parte do texto para ter sucesso. O seguinte exemplo imprime o segundo campo de cada registro que contém os três caracteres '​dev'​ em qualquer posição. ​
 +<sxh bash>
 +awk '/dev/ { print $2 }' /etc/fstab
 +</​sxh>​
 +
 +Expressões regulares também podem ser usadas na correspondência de expressões. Estas expressões permitem especificar uma string a ser procurada que não precisa ser todo o registro de entrada. Os operadores ~ e !~ realizam comparações de expressões regulares. Expressões que usam estes operadores podem ser usadas como um padrão ou em comandos if, while, for e do. Por exemplo: ​
 +
 +<sxh bash>
 +~ /<​expressão_regular>/ ​
 +</​sxh>​
 +
 +Retorna verdadeiro se a expressão <exp> corresponder a <​expressão_regular>​.
 +
 +Os próximos exemplos são usados para "​selecionar"​ todos os registros de entrada que possuem a letra '​a'​ em algum lugar do primeiro campo. ​
 +<sxh bash>
 +awk '$1 ~ /a/' /​etc/​inittab
 +awk '{ if ($1 ~ /a/) print }' /​etc/​inittab
 +</​sxh>​
 +
 +Quando uma expressão regular está entre /, ela é chamada de expressão regular constante (5.27 é uma constante numérica e "​awk"​ é uma constante do tipo string).
 +
 +====== Escape Sequences ======
 +Alguns caracteres não podem ser incluídos "​literalmente"​ em expressões regulares constantes. Neste caso eles são representados com escape sequences, que são seqüências de caracteres que começam com \.
 +
 +Isto é útil, por exemplo, para incluir " numa constante do tipo string. Por exemplo: ​
 +<sxh bash>
 +awk 'BEGIN { print "Ele disse \"​Oi!\"​ para ela." }'
 +</​sxh>​
 +
 +O próprio caracter \ não pode ser incluído normalmente;​ deve-se colocar '​\\'​ para que um '​\'​ faça parte da string.
 +
 +O caracter \ também é usado para representar caracteres que não podem ser exibidos, tais como tab ou newline. Outras utilizações são apresentadas abaixo: ​
 +^ Caracter ^ Representa ^
 +|<​nowiki>​\\</​nowiki> ​ |\|
 +|\/ |/|
 +|\" |"|
 +|\a |Caracter de alerta (beep)|
 +|\t |tab horizontal|
 +|\v |tab vertical|
 +|\b |Backspace|
 +|\f |Formfeed|
 +|\n     ​|Newline|
 +|\r |Carriage return|
 +
 +====== Operadores de Expressões Regulares ======
 +
 +Expressões regulares podem ser combinadas com caracteres chamados de operadores de expressões regulares ou metacaracteres,​ apresentados a seguir.
 +
 +  * **\** É usado para suprimir o significado especial de um caracter quando encontrado. Por exemplo: \$, corresponde ao caracter $
 +  * **^** Corresponde ao início de uma string. Por exemplo: ^@chapter, corresponde a uma string que começa com '​@chapter'​.
 +  * **$** É similar a ^, mas corresponde ao fim de uma string. Por exemplo: p$, corresponde a um registro que termina do '​p'​.
 +  * **.** O ponto corresponde a um único caracter, incluindo newline. Por exemplo: .P, corresponde a qualquer caracter seguido por P em uma string.
 +  * **[..]** Esta é a chamada lista de caracteres. Corresponde aos caracteres que estão entre [ e ]. Por exemplo: [MVX], corresponde a qualquer um dos caracteres '​M',​ 'V ou '​X'​ em uma string. Um intervalo é indicado por um hífen (exemplo: [0-9]). Classe de caracter é uma notação especial para descrição de listas de caracteres que possuem um atributo específico. Uma classe de caracter consiste de: [: :]. Algumas classes de caracteres são: 
 +  * **[:​alnum:​]** caracteres alfanuméricos ​
 +  * **[:​alpha:​]** caracteres alfabéticos ​
 +  * **[:​blank:​]** espaço e tab 
 +  * **[:​digit:​]** caracteres numéricos ​
 +  * **[:​cntrl:​]** caracteres de controle ​
 +  * **[:​print:​]** caracteres que podem ser impressos(- caracteres de controle) ​
 +  * **[:​punct:​]** caracteres de pontuação ​
 +
 +Uma classe de equivalência é um nome para uma lista de caracteres que são equivalentes,​ que deve estar entre [= e =]. Por exemplo: e pode ser usado para representar e, é ou è. Neste caso, [[=e]] é uma expressão regular que corresponde a qualquer um destes caracteres (e,é,è).
 +  * **[^..]** Corresponde a qualquer caracter exceto os listados. Por exemplo: [^0-9] corresponder a qualquer caracter que não é um dígito.
 +  * **|** É um operador usado para especificar alternativas. Por exemplo: ^P|[0-9] corresponde a qualquer string que começa com P ou contém um dígito.
 +  * **(..)** São usados para agrupar expressões regulares, assim como aritméticas.
 +  * <​nowiki>​*</​nowiki>​ Este símbolo significa que a expressão regular precedente pode ser repetida quantas vezes for necessário. Por exemplo: ph* corresponde a um p seguido de vários h.
 +  * **+** É similar a *, a expressão precedente deve aparecer pelo menos uma vez. Isto significa que wh+y corresponde a why e whhy, mas não wy.
 +  * **?** É similar a *, mas a expressão precedente deve aparecer uma ou nenhuma vez. Por exemplo: fe?d corresponde a fed e fd.
 +  * **{n} {n,} {n,m}** Um ou dois números entre { e } denota uma expressão de intervalo. Por exemplo: wh{3}y corresponde a whhhy, mas não a why ou whhhhy; wh{3,5}y corresponde somente a whhhy, ou whhhhy ou whhhhhy; wh(2,​}y ​ corresponde a whhy ou whhhy e assim por diante.
 +
 +Em expressões regulares os operadores *, + e ?, bem como { e }, possuem a maior precedência,​ seguidos pela concatenação e por |. Parênteses podem mudar como os operadores são agrupados.
 +
 +====== Case-sensitivity ======
 +
 +A correspondência de caracteres é case-sensitive. Isto significa que um w em uma expressão regular corresponde somente a w e não W. A maneira mais simples de solucionar este problema é usar uma lista de caracteres [Ww]. Entretanto isto pode tornar a leitura de expressões regulares mais difícil. Outra maneira é usar as funções tolower ou toupper. Por exemplo: ​
 +<sxh bash>
 +tolower($1) ~ /foo/ {...} 
 +</​sxh>​
 +Converte o primeiro campo para minúsculas antes de fazer a comparação.
 +
 +Outra maneira ainda é setar a variável **IGNORECASE** para um valor não zero, pois neste caso as operações com expressões regulares e string ignoram a diferença entre maiúsculas e minúsculas. Por exemplo: ​
 +<sxh bash>
 +x = "​aB" ​
 +if (x ~ /ab/) ... # este teste irá falhar ​
 +IGNORECASE = 1 
 +if (x ~ /ab/) ... # agora irá funcionar
 +</​sxh>​
 +
 +====== Comandos de Controle em Ações ======
 +
 +Comandos de controle tais como if e while, controlam o fluxo de execução em programas awk. A maioria deles são similares as comandos da linguagem C.
 +
 +**Comando if-else: **
 +
 +Sintaxe do comando
 +<sxh bash>
 +if (<​condição>​) { <​comandos>​ } 
 +if (<​condição>​) { <​comandos>​ } else { <​comandos>​ } 
 +</​sxh>​
 +
 +Exemplo do comando if-else: ​
 +<sxh bash>
 +if ( x % 2 == 0 ) 
 +   print "x eh par" ​
 +else 
 +   print "x eh impar" ​
 +ou 
 +if ( x % 2 == 0 ) print "x eh par"; else 
 +  print "x eh impar"
 +</​sxh>​
 +
 +**Comando while: **
 +
 +Sintaxe do comando while
 +<sxh bash>
 +while (<​condição>​) ​
 +
 +    <​comandos> ​
 +
 +</​sxh>​
 +
 +Exemplo do comando while:
 +<sxh bash> ​
 +awk '{ i = 1 
 +  while ( i <= 3 ) { 
 +    print $i 
 +    i++ 
 +   ​} ​
 +}' lista1.txt
 +
 +**Comando do-while: **
 +
 +Sintaxe do comando do-while
 +<sxh bash>
 +do { 
 +  <​comandos> ​
 +} while ( <​condição>​ ) 
 +</​sxh>​
 +
 +Exemplo do comando do-while: ​
 +<sxh bash>
 +awk '{ i = 1 
 +  do { 
 +    print $0 
 +    i++ 
 +  } while ( i<= 10 ) 
 +}' lista1.txt
 +</​sxh>​
 +
 +**Comando for: **
 +
 +Sintaxe do comando for
 +<sxh bash>
 +for( <​inicialização>;​ <​condição>;​ <​incremento>​ ) 
 +  <​comandos> ​
 +</​sxh>​
 +
 +Exemplo do comando for: 
 +<sxh bash>
 +awk '{ for (i=1; i<=3; i++) 
 +   print $i 
 +     ​}'​ lista1.txt
 +</​sxh>​
 +
 +**Comando break:** Força o término imediato do laço de onde é chamado (for, while ou do). Ele não tem significado quando usado fora do corpo de um laço.
 +
 +**Comando continue:** Assim como o break, é usado somente dentro de um laço (for, while ou do). Ao invés de forçar o término do laço, este comando faz com que ocorra a próxima iteração do laço, pulando qualquer código intermediário.
 +
 +**Comando next:** Força o awk a parar imediatamente de processar o registro corrente e passar para o próximo registro.
 +
 +**Comando nextfile:** Similar ao comando next, ao invés de abandonar o processamento do registro corrente, o comando nextfile instrui o awk a parar de processar o arquivo corrente.
 +
 +**Comando exit:** Faz com que o awk pare imediatamente de processar a regra corrente e pare de processar a entrada; qualquer entrada restante é ignorada.
 +
 +====== Comandos print e printf ======
 +
 +O print é um comando de saída simples (padrão). Já o printf é usado quando se deseja uma saída formatada.
 +
 +O comando print exige simplesmente a especificação da lista de números, strings, variáveis, expressões awk e/ou campos do registro corrente (tal como $1), que devem ser exibidos, separados por vírgula. Eles são, então, exibidos separados por espaços em branco e seguidos por uma nova linha. Opcionalmente,​ a lista de números e strings pode ser colocada entre parênteses.
 +
 +O print sem um item especificado,​ é equivalente a print $0, e imprime todo o registro corrente. Para imprimir uma linha em branco usa-se print "",​ onde ""​ é a string vazia.
 +
 +Exemplos do comando print: ​
 +<sxh bash>
 +awk 'BEGIN { print "line one \nline two \nline three" }' ​
 +awk '{ print $1 $2 }' lista1.txt ​
 +awk 'BEGIN { print "​Campo1 Campo2" ​
 +  print "​------ ------" ​
 +   ​} ​
 +{ print $1, " ", $2 }' lista1.txt
 +</​sxh>​
 +
 +O default no comando print é separar os campos com um espaço em branco. Entretanto, qualquer seqüência de caracteres pode ser usada, basta inicializar a variável OFS (Output Field Separator). Da mesma maneira, é possível trocar a forma de separar os registros, cujo default é uma nova linha. Neste caso, deve-se inicializar a variável ORS (Output Record Separator). Por exemplo: ​
 +<sxh bash>
 +awk 'BEGIN { OFS = ";";​ ORS = "​\n\n"​ } 
 +>          { print $1, $2 }' lista1.txt ​
 +Carla;​3226.12.12 ​
 +Ivan;​3340.11.00 ​
 +Maria;​3223.78.21 ​
 +Regis;​3332.12.21
 +</​sxh>​
 +Para se ter um controle mais preciso da formatação,​ bem como para alinhar colunas de dados de uma maneira fácil, utiliza-se printf. Com printf é possível especificar a largura que será usada para cada item e várias maneiras de formatar números. Este comando é usado da seguinte maneira: ​
 +<sxh bash>
 +printf formato, item1, item2, ... 
 +</​sxh>​
 +
 +Onde o formato é muito semelhante ao ANSI C (ex.: %c, %s, %i, %4.3f). ​
 +Exemplo da utilização do printf: ​
 +<sxh bash>
 +awk '{ printf "%-10s %s\n", $1, $2 }' lista1.txt ​
 +Carla 3226.12.12 ​
 +Ivan 3340.11.00 ​
 +Maria 3223.78.21 ​
 +Regis 3332.12.21
 +</​sxh> ​    
 +
 +====== Array em Awk ======
 +
 +Um array é uma tabela de valores, chamados elementos. Os elementos de um array são distinguidos por índices. Índices em awk podem ser tanto números como strings, e cada array deve ter um nome (mesma sintaxe dos nomes de variáveis).
 +
 +Arrays em awk são semelhantes às outras linguagens, mas existem algumas diferenças fundamentais. Em awk não é necessário especificar o tamanho de um array antes de começar a usá-lo. Adicionalmente,​ qualquer número ou string pode ser usado como indice do array, e não apenas números inteiros consecutivos.
 +
 +Na verdade, Arrays em awk são associativos. Isto significa que cada array é uma coleção de pares: um índice, e o valor do elemento correspondente,​ como exemplificado abaixo: ​
 +<sxh bash>
 +Elemento 4        Valor 30 
 +Elemento 2        Valor "​awk" ​
 +Elemento 1        Valor 8 
 +Elemento 3        Valor "" ​
 +</​sxh>​
 +Os pares acima estão fora de ordem porque a ordem é irrelevante.
 +
 +Uma vantagem do array associativo é que novos pares podem ser adicionados em qualquer momento. Para ilustrar, no exemplo anterior é possível inserir o valor "​numero 10" na décima posição: ​
 +<sxh bash>
 +Elemento 10     Valor "​numero 10" ​
 +Elemento 4        Valor 30 
 +Elemento 2        Valor "​awk" ​
 +Elemento 1        Valor 8 
 +Elemento 3        Valor "" ​
 +</​sxh>​
 +Desta maneira o array fica esparso, isto é, faltam alguns índices.
 +
 +Outra conseqüência dos arrays associativos é que os índices não precisam ser números inteiros positivos. Por exemplo, logo abaixo é apresentado um array que traduz palavras do Inglês para o Francês: ​
 +<sxh bash>
 +Element "​dog" ​     Valor "​chien" ​
 +Element "​cat" ​      Valor "​chat" ​
 +Element "​one" ​    Valor "​un" ​
 +Element 1             Valor "​un" ​
 +</​sxh>​
 +
 +Um cuidado que deve ser tomado, é que letras maiúsculas são diferentes de minúsculas,​ e o valor de IGNORECASE não tem efeito. Deve-se usar a mesma string para armazenar e recuperar um elemento do array.
 +
 +Quando awk cria um array, por exemplo com uma função, o array criado possuirá índices inteiros consecutivos que começam em um.
 +
 +A principal maneira de usar um array é referenciar um dos seus elementos, da seguinte maneira: ​
 +<sxh bash>
 +nome_array[índice] ​
 +</​sxh>​
 +Se for usada uma referência para um elemento que não está armazenado, o valor resultante é ""​ (string nula).
 +
 +É possível verificar se um elemento, num certo índice, existe em um array com a expressão: ​
 +<sxh bash>
 +índice in nome_array ​
 +</​sxh>​
 +Assim, pode-se testar quando um índice existe ou não. Se nome_array[índice] existe, é retornado o valor 1 (verdadeiro),​ caso contrário é retornado 0 (falso).
 +
 +O exemplo abaixo ilustra a utilização de arrays. ​
 +<sxh bash>
 +vim array.awk
 +#! /bin/awk -f 
 +# Comandos que serao executados antes de varrer o arquivo ​
 +BEGIN { 
 +     print "Este programa ordena um arquivo cujas linhas sao numeradas!\n" ​
 +
 +# Comandos que serao executados depois de varrer o arquivo ​
 +END { 
 +     print "​Arquivo Ordenado: \n" ​
 +     for (i=1; i<=max; i++) 
 +       if (i in vetor) # para evitar linhas em branco ​
 +         print vetor[i] ​
 +     ​} ​
 +# Comandos que serao executados enquanto varre o arquivo ​
 +  { 
 +   if ($1 > max) 
 +           max = $1 
 +         ​vetor[$1] = $0 
 +  }
 +</​sxh>​
 +Para percorrer todos os elementos de um array cujos índices não são números inteiros em ordem crescente, awk possui um comando for "​especial": ​
 +<sxh bash>
 +for ( var in array ) 
 +   <​comandos> ​
 +</​sxh>​
 +Este laço executa os comandos uma vez para índice do array que tenha sido previamente usado no programa, com a variável var "​setada"​ para o índice. Exemplo: ​
 +<sxh bash>
 +#! /bin/awk -f 
 +# Exemplo com array cujos índices não são números inteiros ​
 +# Armazena 1 para cada palavra que é usada pelo menos uma vez 
 +
 +# NF número de campos do registro de entrada corrente ​
 +for (i=1; i<=NF; i++) 
 +   # armazena 1 para cada palavra que é usada pelo menos uma vez 
 +  pal_usadas[$i] = 1 
 +  } 
 +# Comandos que serao executados depois de varrer o arquivo ​
 +  END { 
 +   for (x in pal_usadas) ​
 +        if (length(x)>​10) { 
 +      ++num_pal_longas ​
 +      print x 
 +         ​} ​
 +  print num_pal_longas,​ "​palavras maiores que 10 caracteres!" ​
 +
 +</​sxh>​
 +A ordem na qual os elementos do array são acessados por este comando é determinada pelo awk e não pode ser controlada ou alterada.
 +
 +É possível remover um elemento individual de um array usando o comando delete: ​
 +<sxh bash>
 +delete nome_array[índice] ​
 +</​sxh>​
 +No exemplo abaixo todos os elementos do array são removidos: ​
 +<sxh bash>
 +for (i in vetor) ​
 +delete vetor[i] ​
 +</​sxh>​
 +Torna-se importante salientar que remover um elemento é diferente de atribuir um valor nulo. Por exemplo: ​
 +<sxh bash>
 +delete vetor[4] ​
 +if (4 in vetor) ​
 +   print "Esta mensagem nunca sera exibida." ​
 +   ​vetor[2] = "" ​
 +   if (2 in vetor) ​
 +   print "Esta mensagem sera exibida, apesar de nao ter conteudo." ​
 +</​sxh>​
 +Não é um erro remover um elemento que não existe, e todos os elementos podem ser removidos com um único comando: ​
 +<sxh bash>
 +delete vetor
 +</​sxh>​
 +
 +Awk suporta arrays multidimensionais. Neste caso são usados mais do que um índice separados por vírgula. Também é possível testar quando um índice existe em um array multidimensional usando o mesmo operador in. Exemplo: ​
 +<sxh bash>
 +
 +awk '​{ ​
 +if (max_nf < NF) 
 +max_nf = NF 
 +# NR é o número de registros de entrada processados ​
 +# desde o início da execução do programa ​
 +max_nr = NR 
 +for (x=1; x<=NF; x++) 
 + ​vector[x,​ NR] = $x 
 +
 +END { 
 +for (x=1; x<​=max_nf;​ x++) { 
 +for (y=max_nr; y>=1; --y) 
 +  printf ("​%s",​ vector[x, y]) 
 +  printf("​\n"​) ​
 +   ​} ​
 +  } 
 +}' ​
 +# Dada a entrada: ​
 +# 1 2 3 4 5 6 
 +# 2 3 4 5 6 1 
 +# 3 4 5 6 1 2 
 +# 4 5 6 1 2 3 
 +# O resultado é: 
 +# 4 3 2 1 
 +# 5 4 3 2 
 +# 6 5 4 3 
 +# 1 6 5 4 
 +# 2 1 6 5 
 +# 3 2 1 6
 +</​sxh>​
 +
 +====== Funções Built-in ======
 +
 +Funções Built-in são funções que estão sempre disponíveis para serem chamadas em programas awk. Para chamá-las, basta escrever o nome da função seguida pelos argumentos entre parênteses. Espaços em branco entre o nome da função e (são ignorados, mas recomenda-se que não seja deixado um espaço em branco). Algumas funções Built-in são apresentadas a seguir.
 +
 +  * **sqrt(x)**:​ retorna a raiz quadrada de x
 +  * **int(x):** retorna o número inteiro mais próximo de x (trunca).
 +  * **rand():** retorna um número randômico entre 0 e 1, mas não inclui 0 e 1. Pode-se obter números inteiros randômicos da seguinte maneira: ​
 +<sxh bash>
 +function randint(n) { 
 +      return int(n* rand()) ​
 +}
 +</​sxh>​
 +  * **index(in, find):** procura na string "​in"​ a primeira ocorrência da string "​find"​ e retorna a posição onde foi encontrada dentro da string "​in"​. Exemplo: ​
 +<sxh bash>
 +awk 'BEGIN { print index("​peanut",​ "​an"​) }' ​
 +3
 +</​sxh>​
 +  * **length():​** retorna o número de caracteres da string.
 +  * **split(string,​ array[, fieldsep]):​** divide a string em partes separadas por fieldsep, e armazena as partes no array. O valor de fieldsep é uma expressão regular que descreve onde dividir a string. Se o valor de fieldsep é omitido, o valor de FS é usado. FS é o campo de entrada separador. Se o seu valor for a string nula (""​),​ então cada caracter torna-se um campo separador. O default é " ". split retorna o número de elementos criados. Exemplo: ​
 +<sxh bash>
 +split ("​cul-de-sac",​ a, "​-"​) ​
 +</​sxh>​
 +A função retorna 3 e o array terá o seguinte conteúdo: ​
 +<sxh bash>
 +a[1] = "​cul" ​
 +a[2] = "​de" ​
 +a[3] = "​sac"​
 +</​sxh>​
 +  * **tolower(string):​** retorna uma cópia da string com todos os caracteres minúsculos.
 +  * **toupper(string):​** retorna uma cópia da string com todos os caracteres maiúsculos.
 +
 +====== AWK Para administradores Linux ======
 +
 +
 +A sintaxe dele é a seguinte:
 +<sxh bash>
 +awk '​padrão{ação}'​
 +</​sxh>​
 +
 +Vamos ao nosso primeiro exemplo:
 +
 +Vamos mandar listar todas as linhas do arquivo /etc/passwd que contenham a string root
 +<sxh bash>
 +awk '/​root/​ { print }' /etc/passwd
 +root:​x:​0:​0:​root:/​root:/​bin/​bash
 +operator:​x:​11:​0:​operator:/​root:/​sbin/​nologin
 +</​sxh>​
 +
 +Aqui foram nos mostradas todas as linhas com a string root mais eu quero somente a primeira e a terceira coluna, o awk por padrão usa o espaço para delimitar campos, com isso temos que passar um modificador para ele que é o -F, cada campo é identificado por uma variável $n onde n é o número do campo, o $0 identifica todos os campos.
 +
 +<sxh bash>
 +awk -F ":"​ '/​root/​ { print $1 $3} ' /etc/passwd
 +root0
 +operator11
 +</​sxh>​
 +
 +Note que mesmo nós deixamos separadas as variáveis $1 e $3 a saída apareceu ele juntos vamos ajustar isso agora inserindo entre o $1 e o $3 " "
 +<sxh bash>
 +awk -F ":"​ '/​root/​ { print $1 " " $3} ' /etc/passwd
 +root 0
 +operator 11
 +</​sxh>​
 +
 +Agora ficou melhor a visualização,​ agora pense que precisamos identificar o que são esses campos, podemos fazer da seguinte forma
 +<sxh bash>
 +awk -F ":"​ '/​root/​ { print "​Login:"​ $1 " ID:" $3} ' /etc/passwd
 +Login:root ID:0
 +Login:​operator ID:11
 +</​sxh>​
 +
 +Agora vamos fazer uma pesquisa condicional,​ vamos procurar as linhas que tenham o primeiro campo igual a root ou que contenham a string games
 +<sxh bash>
 +awk -F ":"​ '$1 == "​root"​ || $1 ~ /​games/'​ /etc/passwd
 +root:​x:​0:​0:​root:/​root:/​bin/​bash
 +games:​x:​12:​100:​games:/​usr/​games:/​sbin/​nologin
 +</​sxh>​
 +
 +Vamos ver uma lista dos operadores lógicos do awk:
 +^ Operador ^   ​Nome ​  ^
 +|==  | Igual |
 +|!=  | Diferente|
 +|<   | Menor que |
 +|>   | Maior que |
 +| <​nowiki><​=</​nowiki>​| Menor ou igual|
 +|>= | Maior ou igual |
 +| ~ | Procura por uma expressão regular|
 +| !~ | Que seja diferente da expressão regular|
 +|<​nowiki>​||</​nowiki>​ |OU lógico|
 +| <​nowiki>&&</​nowiki>​ |E lógico|
 +| !|Negação lógica|
 +
 +Vamos ver algumas variáveis do awk
 +^ Variável ^    Descrição ​   ^
 +| NR | Contém o número do registro atual |
 +| NF | Contém o número de registros por campo|
 +| FS | Indica o separador de campos |
 +| RS | Indica o separador de registros |
 +| OFS | Indica o separador de campo do arquivo de saída |
 +| ORS | Indica o separador de registros do arquivo de saída |
 +
 +Vamos testar agora o separador de saída que podemos forçar com o OFS da seguinte forma
 +<sxh bash>
 +awk -F ":"​ '​{OFS="​ - "​}{print $1,​$6}'​ /etc/passwd
 +root - /root
 +bin - /bin
 +daemon - /sbin
 +adm - /var/adm
 +lp - /​var/​spool/​lpd
 +sync - /sbin
 +shutdown - /sbin
 +halt - /sbin
 +mail - /​var/​spool/​mail
 +uucp - /​var/​spool/​uucp
 +operator - /root
 +games - /usr/games
 +gopher - /var/gopher
 +[...]
 +</​sxh>​
 +
 +Agora vamos listar o nome dos grupos que tiverem como membro o usuário daemon
 +<sxh bash>
 +awk -F ":"​ '$4 ~  /daemon/ {print $1}' /etc/group
 +bin
 +daemon
 +adm
 +lp
 +haldaemon
 +</​sxh>​
 +
 +Agora vamos mandar imprimir uma linha especifica por exemplo a linha 6 do arquivo /etc/fstab
 +<sxh bash>
 +awk '​NR==6'​ /​etc/​fstab ​
 +# Accessible filesystems,​ by reference, are maintained under '/​dev/​disk'​
 +</​sxh>​
 +
 +Agora vamos utilizar o awk para mandar imprimir ​ o tamanho da maior linha de um arquivo, vamos utilizar o /​etc/​inittab como exemplo
 +<sxh bash>
 +awk '{ if (length($0) > max) max=length($0) } END { print max }' /​etc/​inittab ​
 +78
 +</​sxh>​
 +
 +Agora vamos mandar imprimir os usuários que tem o GID maior que 499
 +<sxh bash>
 +awk -F ":"​ '{if ($4 > 499) print $1}' /etc/passwd
 +nfsnobody
 +quintiliano
 +_tor
 +</​sxh>​
 +
 +Agora vamos pegar o endereço ip da interface eth0
 +<sxh bash>
 +ifconfig eth0 | awk '/inet end/ {print $3}'
 +10.101.0.1
 +</​sxh>​
 +
 +Agora vamos mandar inverter o endereço ip
 +<sxh bash>
 +ifconfig eth0 | awk '/inet end/ {print $3}' | awk -F "​."​ '{ print $4 "​."​ $3 "​."​ $2 "​."​ $1}'
 +1.0.101.10
 +</​sxh>​
 +
 +Agora vamos pegar todos os endereços ips da máquina
 +<sxh bash>
 +ifconfig | awk '/inet end/ {print $3}'
 +10.101.0.1
 +127.0.0.1
 +</​sxh>​
 +
 +Agora vamos pegar o nome e o endereço MAC de todas as interfaces que temos na máquina
 +<sxh bash>
 +ifconfig | awk '/​eth[0-9]/​ { print $1 " " $7} '
 +eth0 24:​BA:​E9:​BC:​5E:​12
 +eth1 D8:​4A:​35:​D7:​4A:​26
 +</​sxh>​
 +
 +Agora vamos mandar imprimir as linhas do arquivo /etc/passwd e vamos numera-las ​
 +<sxh bash>
 +awk -F ":"​ '{ print NR " " $0 }' /etc/passwd
 +1 root:​x:​0:​0:​root:/​root:/​bin/​bash
 +2 bin:​x:​1:​1:​bin:/​bin:/​sbin/​nologin
 +3 daemon:​x:​2:​2:​daemon:/​sbin:/​sbin/​nologin
 +4 adm:​x:​3:​4:​adm:/​var/​adm:/​sbin/​nologin
 +5 lp:​x:​4:​7:​lp:/​var/​spool/​lpd:/​sbin/​nologin
 +6 sync:​x:​5:​0:​sync:/​sbin:/​bin/​sync
 +7 shutdown:​x:​6:​0:​shutdown:/​sbin:/​sbin/​shutdown
 +8 halt:​x:​7:​0:​halt:/​sbin:/​sbin/​halt
 +9 mail:​x:​8:​12:​mail:/​var/​spool/​mail:/​sbin/​nologin
 +10 uucp:​x:​10:​14:​uucp:/​var/​spool/​uucp:/​sbin/​nologin
 +11 operator:​x:​11:​0:​operator:/​root:/​sbin/​nologin
 +12 games:​x:​12:​100:​games:/​usr/​games:/​sbin/​nologin
 +13 gopher:​x:​13:​30:​gopher:/​var/​gopher:/​sbin/​nologin
 +[...]
 +</​sxh>​
 +
 +Para contarmos a quantidade de linhas de um arquivo por exemplo /etc/passwd podemos fazer da seguinte forma.
 +<sxh bash>
 +awk 'END { print NR }' /etc/passwd
 +38
 +</​sxh>​
 +
 +Agora pense que precisamos de uma determinada coluna em uma determinada linha podemos fazer isso da seguinte forma
 +<sxh bash>
 +awk -F ":"​ 'NR == 1 {print $3}' /etc/passwd
 +0
 +</​sxh>​
 +
 +Neste exemplo acima estamos obtendo o uid do usuário root que é o zero
 +
 +
 +Vamos ver agora como lemos somente uma determinada linha de um arquivo, vamos ler a linha 10 do /etc/passwd
 +<sxh bash>
 +awk 'NR == 30' /etc/passwd
 +rpcuser:​x:​29:​29:​RPC Service User:/​var/​lib/​nfs:/​sbin/​nologin
 +</​sxh>​
 +
 +Vamos localizar os processos no sistema que não são nem do usuário root e nem do nobody e que estão consumindo mais de 2% da memória
 +<sxh bash>
 +ps aux | awk '​!/​root|nobody/​ { if ($4>2) { print $2,​$11}}'​
 +2672 /​opt/​google/​chrome/​chrome
 +3461 /​opt/​google/​chrome/​chrome
 +3481 /​opt/​google/​chrome/​chrome
 +5720 /​opt/​google/​chrome/​chrome
 +15664 /​usr/​lib/​virtualbox/​VirtualBox
 +18143 /​usr/​lib/​virtualbox/​VirtualBox
 +18272 /​usr/​lib/​virtualbox/​VirtualBox
 +</​sxh>​
 +
 +Aqui o !/​root|nobody/​ é uma procurando por processos não sendo do usuário root ou do nobody depois temos $4>2 aonde o quarto campo é o % de memória depois disso mandamos imprimir o campo 2 que é o PID e o campo número 11 que é o aplicativo que o usuário está utilizando.
 +
 +Agora vamos ver como podemos utilizar o awk para visualizarmos os logs do squid por exemplo. Vamos mostrar o endereço ip do usuário e o site que ele esta acessando
 +<sxh bash>
 +tail -f /​var/​log/​squid3/​access.log | awk '​{print "IP: " $3 " Site: " $7}'
 +IP: 10.0.1.128 Site: http://​khm0.google.com.br/​kh/​v=123&​src=app&​x=390&​y=572&​z=10&​s=Galile
 +IP: 10.0.1.128 Site: http://​mt0.google.com/​vt/​lyrs=h@203000000&​hl=pt-BR&​src=app&​x=386&​y=572&​z=10&​s=Ga
 +IP: 10.0.1.128 Site: http://​mt0.google.com/​vt/​lyrs=h@203000000&​hl=pt-BR&​src=app&​x=390&​y=572&​z=10&​s=Galile
 +IP: 10.0.1.128 Site: http://​khm0.google.com.br/​kh/​v=123&​src=app&​x=386&​y=572&​z=10&​s=Ga
 +IP: 10.0.1.128 Site: http://​mt1.google.com/​vt/​lyrs=h@203000000&​hl=pt-BR&​src=app&​x=389&​y=572&​z=10&​s=Gal
 +IP: 10.0.1.128 Site: http://​mt1.google.com/​vt/​lyrs=h@203000000&​hl=pt-BR&​src=app&​x=387&​y=572&​z=10&​s=Galil
 +IP: 10.0.1.128 Site: http://​khm0.google.com.br/​kh/​v=123&​src=app&​x=388&​y=572&​z=10&​s=
 +IP: 10.0.1.128 Site: http://​khm0.google.com.br/​kh/​v=123&​src=app&​x=386&​y=572&​z=10&​s=Ga
 +IP: 10.0.1.128 Site: http://​mt0.google.com/​vt/​lyrs=h@203000000&​hl=pt-BR&​src=app&​x=386&​y=572&​z=10&​s=Ga
 +IP: 10.0.1.128 Site: http://​mt0.google.com/​vt/​lyrs=h@203000000&​hl=pt-BR&​src=app&​x=390&​y=572&​z=10&​s=Galile
 +IP: 10.0.1.128 Site: http://​khm0.google.com.br/​kh/​v=123&​src=app&​x=390&​y=572&​z=10&​s=Galile
 +[...]
 +</​sxh>​
 +
 +Vamos ver uma função para converter a data do squid que é um formato parecido com esse 1356713930.914 para o formato que utilizamos ​
 +<sxh bash>
 +echo "​1356713930.914"​ | awk '​{print strftime("​%F %H:​%M:​%S",​$1)}'​
 +2012-12-28 14:58:50
 +</​sxh>​
 +
 +Aqui ao invés de utilizar %Y%m%d utilizamos o %F que é equivalente,​ porém que eu precisar formatar a data com dd/mm/yyyy precisamos fazer da seguinte forma
 +<sxh bash>
 +echo "​1356713930.914"​ | awk '​{print strftime("​%Y/​%m/​%d %H:​%M:​%S",​$1)}'​
 +2012/12/28 14:58:50
 +</​sxh>​
 +
 +Agora se eu precisamos visualizar a data o ip do cliente e o site podemos fazer da seguinte forma
 +<sxh bash>
 +tail -f /​var/​log/​squid3/​access.log | awk '​{print strftime("​%F %H:​%M:​%S",​$1) " IP:"$3 " Site:" $7}'
 +2012-12-28 15:06:48 IP:​10.0.0.215 Site:​mail.google.com:​443
 +2012-12-28 15:06:49 IP:​10.0.0.213 Site:​http://​www.google.com.br/​imghover?​
 +2012-12-28 15:06:49 IP:​10.0.0.213 Site:​http://​t1.gstatic.com/​images?​
 +2012-12-28 15:06:49 IP:​10.0.0.213 Site:​http://​t0.gstatic.com/​images?​
 +2012-12-28 15:06:49 IP:​10.0.0.213 Site:​http://​t1.gstatic.com/​images?​
 +2012-12-28 15:06:49 IP:​10.0.0.213 Site:​http://​t3.gstatic.com/​images?​
 +2012-12-28 15:06:49 IP:​10.0.0.213 Site:​http://​t0.gstatic.com/​images?​
 +2012-12-28 15:06:49 IP:​10.0.0.213 Site:​http://​t0.gstatic.com/​images?​
 +2012-12-28 15:06:49 IP:​10.0.0.213 Site:​http://​t3.gstatic.com/​images?​
 +2012-12-28 15:06:49 IP:​10.0.0.213 Site:​http://​t0.gstatic.com/​images?​
 +[...]
 +</​sxh>​
 +
 +Em alguns casos precisamos converter um determinado texto de maiúsculo para minúscula ou vice-versa.
 +
 +Vamos converter um texto para maiúsculo
 +<sxh bash>
 +awk '{ print toupper($0)}'​ /etc/passwd
 +ROOT:​X:​0:​0:​ROOT:/​ROOT:/​BIN/​BASH
 +DAEMON:​X:​1:​1:​DAEMON:/​USR/​SBIN:/​BIN/​SH
 +BIN:​X:​2:​2:​BIN:/​BIN:/​BIN/​SH
 +SYS:​X:​3:​3:​SYS:/​DEV:/​BIN/​SH
 +SYNC:​X:​4:​65534:​SYNC:/​BIN:/​BIN/​SYNC
 +GAMES:​X:​5:​60:​GAMES:/​USR/​GAMES:/​BIN/​SH
 +MAN:​X:​6:​12:​MAN:/​VAR/​CACHE/​MAN:/​BIN/​SH
 +LP:​X:​7:​7:​LP:/​VAR/​SPOOL/​LPD:/​BIN/​SH
 +MAIL:​X:​8:​8:​MAIL:/​VAR/​MAIL:/​BIN/​SH
 +[...]
 +</​sxh>​
 +
 +Agora pense que queremos converter um texto de maiúsculo para minúsculo
 +<sxh bash>
 +awk '{ print tolower($0)}'​ /​tmp/​passwdupper
 +root:​x:​0:​0:​root:/​root:/​bin/​bash
 +daemon:​x:​1:​1:​daemon:/​usr/​sbin:/​bin/​sh
 +bin:​x:​2:​2:​bin:/​bin:/​bin/​sh
 +sys:​x:​3:​3:​sys:/​dev:/​bin/​sh
 +sync:​x:​4:​65534:​sync:/​bin:/​bin/​sync
 +games:​x:​5:​60:​games:/​usr/​games:/​bin/​sh
 +man:​x:​6:​12:​man:/​var/​cache/​man:/​bin/​sh
 +lp:​x:​7:​7:​lp:/​var/​spool/​lpd:/​bin/​sh
 +</​sxh>​
 +
 +
 + 
 +====== Referências ======
 +  - http://​cesarakg.freeshell.org/​awk-1.html
 +  - http://​cesarakg.freeshell.org/​awk-2.html
 +  - http://​cesarakg.freeshell.org/​awk-3.html
 +  - http://​www.inf.pucrs.br/​~manssour/​AWK/​index.html