Sie sind auf Seite 1von 5

[ 104 ]

Awk
Caracterstica Busca Substituio Diviso ER crua Ignore M/m Global Como fazer Operador ~, Funo match Funes sub, gensub Funo split /entre barras/ Varivel IGNORECASE

Expresses Regulares

Funo gsub, modicador g

Awk uma linguagem antiga (1977) que combina processamento de texto com estruturas de uma linguagem genrica, possuindo condicionais, operaes aritmticas e ans. Alm do Awk clssico do Unix, tambm existe o GNU Awk, conhecido como gawk, que traz algumas funcionalidades novas e um melhor suporte s expresses regulares. O gawk amplamente utilizado em sistemas Linux. Grande parte dos exemplos deste tpico funcionar em ambas verses. Caso contrrio, ser feita uma meno sobre quais so as caractersticas exclusivas do GNU Awk. As expresses regulares so parte integrante da linguagem. Basta colocar uma expresso entre barras que o Awk saber que aquilo no uma string, e sim uma expresso regular com metacaracteres. Se sua expresso possuir uma barra /, lembre-se de escap-la \/ para evitar problemas. O operador til ~ usado para fazer comparaes de strings com expresses regulares. Para uma comparao inversa, em que o teste retornar sucesso se a expresso no casar com a string, use o operador !~.
if ("Awk" ~ /^A/) { print "Casou" } if ("Awk" !~ /^X/) { print "No casou" }

Captulo 7 ! Linguagens e ferramentas

[ 105 ]

Para fazer testes ignorando a diferena entre maisculas e minsculas, antes mude para 1 o valor da varivel IGNORECASE, que funciona como uma chave que liga e desliga esse comportamento. Mude o valor da varivel para zero quando quiser retornar comparao normal.
IGNORECASE = 1 if ("Awk" ~ /^a/) { print "Casou" }

O Awk do Unix no reconhece essa varivel, ento a nica maneira de simular esse comportamento usando a criatividade: converta a string para minsculas ao fazer o teste e use somente minsculas em sua expresso.
if (tolower("Awk") ~ /^a/) { print "Casou" }

Outra maneira de fazer testes utilizar uma expresso regular para casar linhas especcas de um arquivo. Quando o Awk est processando um arquivo de texto, ele o l linha a linha. A linha da vez guardada na varivel especial $0. Ao colocar uma expresso regular diretamente como um teste, ela ser testada na linha atual (como se fosse $0 ~ /er/) e os comandos do bloco seguinte s sero executados nas linhas que casarem com o padro.
/[0-9]/ { print "Linha com nmeros:", $0 }

Dessa maneira, ca fcil testar expresses regulares na linha de comando, seja com o contedo de um arquivo, seja com um texto vindo da entrada padro (STDIN).
prompt$ echo Awk | awk '/^A/ { print "Casou" }' Casou

[ 106 ]

Expresses Regulares

Outra maneira de casar um texto utilizar a funo match. A vantagem que a cada vez que usada, a funo dene as variveis RSTART e RLENGTH, que guardam o ponto de incio (ndice) e o tamanho do trecho casado pela expresso. No GNU Awk, possvel informar um array como terceiro parmetro para a funo match. Nesse caso, a primeira posio (ndice zero) desse array ser preenchida com o trecho casado pela expresso, e as posies seguintes guardaro o contedo de cada grupo.
match("Awk", /(.)(.)(.)/, resultado) print resultado[0] print resultado[1] print resultado[2] print resultado[3] print RSTART print RLENGTH # Awk # A # w # k # 1 # 3

A substituio feita tradicionalmente pela funo sub, que troca apenas a primeira ocorrncia do padro. Sua irm gsub encarrega-se de fazer a substituio de todas as ocorrncias (global). O detalhe que o texto alterado gravado na prpria varivel que continha o texto original, em vez de ser retornado pela funo. Com isso, no possvel usar strings diretamente, sendo sempre necessrio o uso de uma varivel.
texto = "Awk"; sub(/[A-Za-z]/, ".", texto) print texto texto = "Awk"; gsub(/[A-Za-z]/, ".", texto) print texto # ... # .wk

Se a varivel com o texto no for informada funo, utilizada a varivel especial $0, que contm a linha atual do arquivo processado (ou entrada padro). Assim o uso dessas funes torna-se mais gil.

Captulo 7 ! Linguagens e ferramentas


prompt$ echo Awk | awk 'sub(/[A-Za-z]/, ".")' .wk prompt$ echo Awk | awk 'gsub(/[A-Za-z]/, ".")' ... prompt$ echo Awk | awk 'sub(/.*/, "&&&")' AwkAwkAwk

[ 107 ]

Note que ao usar o caractere & no segundo argumento da funo, ele expandido para o trecho casado pela expresso. Mas este o nico caractere considerado especial no texto substituto, pois as funes sub e gsub no tm suporte aos retrovisores. O GNU Awk criou uma funo nova chamada gensub, que, alm do suporte aos retrovisores, tambm traz outras novidades que visam a contornar as limitaes das outras funes. Uma de suas vantagens que o texto alterado retornado pela funo em vez de ser gravado em uma varivel. H tambm um terceiro argumento numrico que indica qual das ocorrncias deve ser substituda. Se esse argumento for a letra g, todas as ocorrncias sero substitudas.
print gensub(/\w/, ".", "1", "Awk") print gensub(/\w/, ".", "2", "Awk") print gensub(/\w/, ".", "3", "Awk") print gensub(/\w/, ".", "g", "Awk") # .wk # A.k # Aw. # ...

Os retrovisores so indicados por \1, \2 e amigos. Mas como so parte de uma string (entre aspas), devem ser escapados para funcionar: \\1, \\2, ... O retrovisor \0 guarda todo o trecho casado pela expresso.
print gensub(/(.)(.)(.)/, "\\3\\2\\1", "g", "Awk") print gensub(/.*/ , "--\\0--" , "g", "Awk") # kwA # --Awk--

A mesma dica de uso da varivel IGNORECASE tambm vale para a gensub ignorar a diferena entre maisculas e minsculas. Ligue e desligue essa varivel com 1 e 0 conforme precisar dela.

[ 108 ]
IGNORECASE = 0 print gensub(/[a-z]/, ".", "g", "Awk") IGNORECASE = 1 print gensub(/[a-z]/, ".", "g", "Awk") # ... # A..

Expresses Regulares

A acentuao no problema, desde que seu sistema esteja congurado corretamente para o portugus. Conra o valor das variveis de ambiente $LANG e $LC_ALL. Use as classes POSIX para casar os caracteres acentuados. No gawk, voc tambm pode usar o barra-letra \w.
print gensub(/[a-z]/ print gensub(/\w/ , ".", "g", "adbuk") , ".", "g", "adbuk") # ..... # ....... # ....... print gensub(/[[:alpha:]]/, ".", "g", "adbuk")

Use a funo split para fazer a diviso de uma string. Seu segundo argumento o array onde a string dividida ser guardada e o terceiro a expresso regular. Note que o ndice inicial 1 e no 0.
split("A w k", resultado, /[ \t]+/) print resultado[1] print resultado[2] print resultado[3] # A # w # k

Usurios avanados de Awk gostaro de saber que as variveis especiais (separador de registros) e FS (separador de campos) tambm podem ser denidas com uma expresso regular. Apenas se lembre de que como sua denio feita por meio de uma string, preciso escapar as contrabarras \.
RS prompt$ echo "A -- w -- k" | awk -F '[- ]+' '{ print $2 }' w

Por m, se voc estiver utilizando o GNU Awk e quiser testar a compatibilidade de seus scripts com o Awk original do Unix ou outras verses, veja as opes --posix, --traditional e --re-interval.

Das könnte Ihnen auch gefallen