Aula 4 – Controlando a saída de dados
Aula 3 – Prática: lendo um feed RSS | Índice | Aula 5 – Variáveis e arrays
Seu apoio é muito importante para a criação e a manutenção dos cursos gratuitos do canal debxp:
Nesta aula…
- A instrução ‘print’
- Separadores de saída
- Formatando saídas numéricas
- Formatando a saída com a instrução ‘printf’
- Redirecionando a saída para arquivos
- Redirecionando a saída para comandos
Controlando a saída de dados
O AWK possui todo um conjunto de recursos que nos permitem controlar a forma como os dados serão exibidos na saída.
A instrução ‘print’
A instrução print produz uma saída com formato padronizado, onde nós só precisamos especificar os valores a serem exibidos separados (ou não) por vírgulas.
Sem a vírgula, os valores serão concatenados:
:~$ awk 'BEGIN { print "a" 123 "b" }'
a123b
Com a vírgula, os valores serão separados por um espaço:
:~$ awk 'BEGIN { print "a", 123, "b" }'
a 123 b
Sem uma lista de valores, todo o registro atual será exibido:
:~$ awk '{ print }' <<< 'banana laranja abacate'
banana laranja abacate
:~$ awk '{ print $0 }' <<< 'banana laranja abacate'
banana laranja abacate
A lista de valores pode ser escrita entre parêntesis:
:~$ awk 'BEGIN { print ("banana", "laranja", "abacate") }'
banana laranja abacate
Importante! Os parêntesis são obrigatórios se algum dos valores for uma expressão com o operador relacional
>
, já que isso pode ser confundido com um redirecionamento de saída.
Separadores de saída
O AWK permite a alterações dos caracteres utilizados por padrão como separadores da saída.
Separador de campos de saída (OFS)
O espaço é o separador padrão da saída de dados, mas outras strings também podem ser configuradas para serem utilizadas através da variável interna OFS
.
:~$ frutas='banana laranja abacate'
:~$ awk 'BEGIN { OFS=" + " } { print $1, $2, $3 }' <<< "$frutas"
banana + laranja + abacate
O separador de saída só funciona com listas de valores separados por vírgula, até porque valores separados com espaços serão concatenados, e a saída do
$0
) é tratada como apenas um valor (um registro).
:~$ frutas='banana laranja abacate'
:~$ awk 'BEGIN { OFS=" + " } { print }' <<< "$frutas"
banana laranja abacate
Separador de registros de saída (ORS)
Da mesma forma, o separador padrão da saída inteira do print
(que é considerada um registro de saída pelo AWK) é a quebra de linha (\n
), e nós podemos alterar isso através da variável interna ORS
.
:~$ awk '{ print }' <<< $linhas
a b c
d e f
g h i
:~$ awk 'BEGIN { ORS=" - " } { print }' <<< $linhas
a b c - d e f - g h i - :~$
Formatando saídas numéricas
Internamente, o AWK converte valores numéricos em strings utilizando a função sprintf()
que, assim como a função printf()
, aceita especificadores de formato.
Especificando formatos de saída (OFMT)
Por padrão, os formatos numéricos são especificados como "%.6g"
, que exibe números reais com seis casas decimais e aplica a notação exponencial quando isso resultar no formato que utiliza menos caracteres. Este padrão pode ser alterado através da variável interna OFMT
.
:~$ awk 'BEGIN { OFMT="%.0f"; print 3.3, 3.5, 3.7 }'
3 4 4
Segundo as normas POSIX, o comportamento do AWK é indefinido caso a especificação de formato em
OFMT
seja qualquer coisa diferente de uma conversão de ponto flutuante.
Formatando a saída com a instrução ‘printf’
O AWK implementa a função printf
, conhecida de diversas linguagens, como uma instrução builtin e com uma sintaxe bastante semelhante à do shell:
printf "FORMATO", valor1, valor2, ...
Os parêntesis são opcionais, mas, assim como na instrução print
, eles passam a ser obrigatórios se algum dos valores for uma expressão contendo o operador relacional >
.
A diferença entre o uso do print
e do printf
é apenas a string de formato, que pode conter qualquer combinação de textos e especificadores de formato. Cada especificador de formato irá corresponder posicionalmente a um valor da lista de valores:
printf "%esp1 %esp2", valor1, valor2
Mas isso também pode ser controlado pelo modificador N$
:
:~$ awk 'BEGIN { printf "%s %s\n", "banana", "laranja" }'
banana laranja
:~$ awk 'BEGIN { printf "%2$s %1$s\n", "banana", "laranja" }'
laranja banana
A lista de especificadores e modificadores aplicáveis ao
printf
longa demais para ser vista em apenas uma aula. Por este motivo, tentaremos explicar seus usos à medida em que formos apresentando exemplos. Para uma lista completa, consulte o manual do AWK.
Redirecionando a saída para arquivos
Em vez de mandarmos a saída do AWK para a saída padrão (stdout), é muito comum queremos que o resultado do processamento seja enviado diretamente para um arquivo, o que pode ser feito facilmente através de um redirecionamento.
Redirecionando para um novo arquivo:
Neste caso, apenas o primeiro registro causará a ciração de um novo arquivo de destino "zerado" (sobrescrevendo arquivos existentes). Os demais registros serão anexados ao final do arquivo criado.
awk '{ print > "arquivo-destino" }' arquivo-de-dados
Redirecionando para o final de um arquivo (append):
Já aqui, nenhum novo arquivo será criado (a menos que ele não exista) e todos os registros serão anexados ao final do arquivo de destino.
awk '{ print >> "arquivo-destino" }' arquivo-de-dados
Redirecionando a saída para comandos
Também é possível enviar a saída das instruções print
e printf
para um comando externo ao AWK através de um pipe. Por exemplo:
datas=$'20201026\n20190313\n20180707'
awk '{
cmd = "date +\"%d de %B de %Y\" -d "$0"";
print | cmd
}' <<< "$datas"
Resultaria em…
26 de outubro de 2020
13 de março de 2019
07 de julho de 2018
Aula 3 – Prática: lendo um feed RSS | Índice | Aula 5 – Variáveis e arrays