linhas de comando e scripts com uso do awkq, espaço para minhas colinhas sobre awk.
Awk é uma linguagem com muitas funcionalidades, excelente na manipulação de strings e arquivo texto, muito útil pra usar na linha de comando, em scripts, em combinação com outros aplicativos como cat, ls e etc...
Definição em: awk -info
, retorna.
gawk é uma linguagem de processamento e busca de padrões. Por padrão, o gawk lê a entrada padrão e escreve na saída padrão.
awk é uma linguagem, simples mas poderosa, para manipular arquivos de dados (e mais). Por exemplo, sendo data.dat seu arquivo de dados multi-campos.
$ awk '$2 ~ "abc" {print $1, "\t", $4}' data.dat
imprime os campos 1 e 4 de cada linha de data.dat cujo segundo campo contenha "abc".
O awk é perfeito pra tarefas em arquivos formatados em colunas, pode usar print $X onde X é a coluna a ser impressa, pode aplicar diretamente em um arquivo texto ou no resultado de comandos passado pelo pipe "|"
Digite na caixa de pesquisa do www.google.com.br, define:awk
pesquise também por gawk, define:gawk
Tradutor do google.
http://translate.google.com/translate_t
CTRL+T abre outra aba no browser para colar a URL que deseja traduzir.
Já que está procurando no google, aproveite e faça a pesquisa, coloque o termo que procure e acrescente +awk ~linux, exemplo para apagar linha:
apagar linha +awk ~linux
AWK faz parte da maioria das distro, caso não instalou ou removeu, para instalar procure pelo pacote; awk ou gawk
Ajuda:
Man awk awk --help gawk --help
Algumas sugestões de pesquisa no Google:
Re: awk ~linux awk ~linux how to awk ~linux define:awk
$0 Pode ser um arquivo inteiro, registro completo, linha corrente completa. Indica e representa tudo, isto depende do que o awk está tratando.
Exemplo para imprimir o arquivo de senhas.
awk '{ print $0 }' /etc/passwd
Tem o mesmo resultado de: cat /etc/passwd
Imprimir somente usuários com UID igual a 1.000 ou maior.
awk -F: '$3 > 999 {print $0}' /etc/passwd
$1 $2 ... indica o campo, onde $1 é referencia ao campo 1, $2 campo 2 e assim por diante, isto depende do delimitador utilizado para separar os campos.
pegar somente o campo 1 do arquivo de usuários.
awk -F ":" '{print $1}' /etc/passwd
cat /etc/passwd | awk -F ":" '{print $1}'
Campo 1 e 3
awk -F ":" '{print $1,$3}' /etc/passwd
man awk
-F fs --field-separator fs Use fs for the input field separator (the value of the FS prede- fined variable).
usando _
como delimitador
echo "usando_em_lugar_do_ponto_ou_espacos" | awk -F\_ '{print $5 ; }'
Onde;
-F\_ indica o delimitador _, a barra \ funciona como escape para o shell não interpretar o _
print $5 indica para pegar a quinta ocorrencia, neste exemplo retorna "ponto", trocando por 3 (print $3) retorna lugar.
trocando a barra \ por aspas " " para informar o delimitador
echo "usando_em_lugar_do_ponto_ou_espacos" | awk -F"_" '{print $5 ; }'
usando espaço
como delimitador
echo "usando em lugar do ponto ou espacos" | awk -F" " '{print $5 ; }'
echo "usando_em_lugar_do_ponto_ou_espacos" | awk -F"_" '{print $5 ; }'
alterar o delimitador _ para espaços e acrescentar (acrescentou) na sexta posição.
echo "usando_em_lugar_do_ponto_ou_espacos" | awk -F"_" '{printf"%s=%s=%s=%s=%s=%sacrescentou=%s\n",$1,$2,$3,$4,$5,$6,$7}'
usando=em=lugar=do=ponto=ouacrescentou=espacos
Manipular arquivo.txt, conteúdo.
SP lampadas 5.102 130.203 2.155,58 206,45 RS fluoresc 6.402 130.215 816,45 79.13 AC lampadas 6.102 129.452 4.421,85 0,00 RO luminari 6.102 129.854 1.092,15 0,00
Juntar coluna 2 e 3, observe que não tem espaço entre (%s%s), acrescentar a palavra "entregue" depois da coluna 4, formatar as colunas de valores 5 e 6, com 14 caracteres cada e imprimir alinhado à direita, observe que $s imprime na ordem da seleção, o primeiro %s imprime $1, caso queira outra coluna lugar, altere a ordem da seleção das colunas, aqui estão na ordem mas pode alterar para algo como $4,$1,$5. portanto, para alterar a ordem de impressão tem que alterar na ordem da seleção.
awk -F" " '{printf"%s %s%s %s entregue%14s%14s\n",$1,$2,$3,$4,$5, $6}' /tmp/teste/arquivo.txt > /tmp/teste/arqnovo.txt Conteúdo do arquivo criado (arqnovo.txt SP lampadas5.102 130.203 entregue 2.155,58 206,45 RS fluoresc6.402 130.215 entregue 816,45 79.13 AC lampadas6.102 129.452 entregue 4.421,85 0,00 RO luminari6.102 129.854 entregue 1.092,15 0,00 entregue
Imprimir somente as colunas 1 3 5 e 6, faça a seleção dos campos como no exemplo abaixo ($1,$3,$5,$6)
awk -F" " '{printf"%s %s %14s%14s\n",$1,$3,$5,$6}' /tmp/teste/arquivo.txt > /tmp/teste/arqnovo.txt cat arqnovo.txt SP 5.102 2.155,58 206,45 RS 6.402 816,45 79.13 AC 6.102 4.421,85 0,00 RO 6.102 1.092,15 0,00
No exemplo acima pega a coluna completa, no exemplo abaixa pega uma faixa de caracteres da coluna, ou seja, pega a coluna e depois seleciona parte dela
awk '{ print substr ($4,5,3)}' /tmp/teste/arquivo.txt > /tmp/teste/arqnovo.txt cat /tmp/teste/arqnovo.txt 203 215 452 854 Onde: ($4,5,3) $4 = igual a coluna do arquivo, altere para coluna desejada. 5 = posição inicial 3 = quantidade de caracteres a pegar a partir da da posição 5 ou seja, pega da coluna 4 o caracteres entre 5 e 8.
Exemplo com o comando ls -la para listar somente tamanho e nome de arquivo
CL 10
ls -la |awk '{print $5" "$8}'
1228107776 arquivao.gdb 52428800 part_aa 52428800 part_ab 52428800 part_ac 52428800 part_ad 52428800 part_ae 30668800 part_af
SUSE 10.1
ls -la |awk '{print $5" "$9}'
Onde:
$5 mostra o tamanho do arquivo
$8 mostra o nome do arquivo.
Invertendo a ordem, colocando o $8 primeiro e $5 depois, também vai inverter o resultado na linha, no primeiro exemplo exibe o tamanho do arquivo e depois o nome, com a inversão passa exibir no resultado o nome do arquivo e depois o tamanho, faça um teste com estes exemplos:
ls -la |awk '{print $5" "$8}'
ls -la |awk '{print $8" "$5}'
Listar IP e site.
tail -f /var/log/squid/access.log |awk '{print "IP: "$3" site: "$7}'
O log pode ser diferente conforme a versão do Squid, o exemplo acima funciona no SUSE 10.1, ajuste as colunas "$3" "$7 coforme os logs no seu sistema, altere para usuários ou outra coluna que deseja exibir.
Ordenar uma lista de palavras com sort, neste exemplo, pegar todos usuários em /etc/passew e listar por ordem de nome.
awk -F: '{print $1}' /etc/passwd | sort
Para salvar em aquivo basta acrescentar o redirecionador > e nome do arquivo.
awk -F: '{print $1}' /etc/passwd | sort > arqusers.txt
Listar nome e ID, primeira e terceira coluna do arquivo de senhas. (zago:x:1000), no exemplo abaixo imprime dois espaços entre as colunas, no segundo exemplo inverte a ordem, primeiro o ID e depois o nome.
awk -F: '{print $1 " " $3}' /etc/passwd | sort
awk -F: '{print $3 " " $1}' /etc/passwd | sort
length() contar string.
Retorna o número de caracteres do dado recebido, pode ser de uma variável ou de arquivo, por default o espaço é o separador, portanto fique atento, pode retornar contagem de palavras em lugar de linhas, veja alguns exemplos abaixo e faça testes.
Contar bytes da coluna de um arquivo, no exemplo abaixo altere $1 para o numero da coluna que deseja contar, $0 conta a linha inteira.
awk '{ print length ($1)}' arquivo.txt
cat arquivo.txt | awk '{ print length ($1)}'
$0 conta a linha inteira, contagem por linha, retorna lista com numero de bytes por linha
cat arquivo.txt | awk '{ print length ($0)}'
cat arquivo.txt | awk '{print length($0)}'
MVAR="contar bytes da variável"
echo $MVAR | awk '{print length($0)}'
24
Contar os bytes da segunda palavra.
echo $MVAR | awk '{print length($2)}'
5
MVAR2=`echo $MVAR | awk '{print length($2)}'`
echo $MVAR2
5
pegar a posição inicial da substring
echo $MVAR | awk '{print index($0,"bytes")}' 8 echo $MVAR | awk '{print index($0,"vel")}' 22
MVAR="TEXTO EM minusculo"
echo $MVAR | awk '{print toupper($0)}'
TEXTO EM MINUSCULO
echo $MVAR | awk '{print tolower($0)}'
texto em minusculo
Contador de lilnhas, retorna o numero total de linhas do arquivo informado (arquivo.txt), incluindo as linhas em branco.
NR = numero de registros, ou numero de linhas quando contando as linhas como registro de um arquivo.
awk 'END { print NR }' arquivo.txt
Lista arquivo sem as linhas linhas em branco
awk 'NF>0' arquivo.txt
Eliminar linhas em branco e redirecionar resultado para outro arquivo.
awk 'NF>0' arquivo.txt > arqlimpo.txt
Passar para variável MEUIP o conteúdo da linha 10 do arquivos arqtemp.txt
Esta linha de comando salva o IP da conexão na linha 10 do arquivo arqtemp.txt
lynx -dump http://www.modemclub.com.br/cgi-bin/mostraip.cgi > arqtemp.txt
As duas linhas abaixo; cria a variável com o IP (linha 10) e na linha seguine echo exibe o conteúdo.
MEUIP=`awk 'NR == 10' arqtemp.txt`
echo $MEUIP
Pegar coluna de linha especifica, exemplo da coluna 2 na linha 5
MMODIF=$(stat /tmp/teste/comandos.txt | awk 'NR == 5 {print $2}' ) echo $MMODIF 2006-07-22
awk strftime'("%c", systime())' awk '{print strftime("%c", systime(),$1)}'
No inicio da linha de log do Squid aparece um numero semelhante a este
1085173079.594
Exemplo de uma linha de log do Squid.
1085173079.594 16 192.168.1.46 TCP_MISS/200 2435 GET http://192.168.1.3/programas/ - DIRECT/192.168.1.3 text/html
Este numero representa a data e hora no formato Unix, (Unix Timestamp). Converter esta data para formato legivel (hora humana), por exemplo, nos log do Squid a data vem neste formato: 1085173079.594, o que vem depois do ponto são milesimos de sengundo que não interessa na data, mesmo porque não usamos este formato de tempo, na conversão elimine o ponto e o que vem depois dele.
Com awk, converter e inverter a ordem para indexar por ano mes e dia.
echo "1085173079" | awk '{print strftime("%F %H:%M:%S",$1)}' 2004-05-21 17:57:59 echo "1085173079" | awk '{print strftime("%F",$1)}' 2004-05-21 echo "1085173079" | awk '{print strftime("%F",$0)}' 2004-05-21
No exemplo acima a formatação "%F" é uma forma abreviada do comando date, esta opção do date está sendo usada na função strftime do awk, equivale a (%Y-%m-%d) e retorna a data no formato ano-mes-dia, veja o exemplo abaixo com troca de (%F) por (%Y-%m-%d) e obtendo o mesmo resultado.
echo "1085173079" | awk '{print strftime("%Y-%m-%d %H:%M:%S",$1)}' 2004-05-21 17:57:59
Para obter a data em outros formatos, altere a formatação como nos exemplos abaixo, observe a troca de "%F" por outros formatos. Para ver todas opções, consulte o man do date (man date). faça testes com todas opções encontradas no manual da date, combine as opções até conseguir o resultado desejado.
echo "1085173079" | awk '{print strftime("%Y%m%d %H:%M:%S",$1)}' 20040521 17:57:5 echo "1085173079" | awk '{print strftime("%Y/%m/%d %H:%M:%S",$1)}' 2004/05/21 17:57:59 echo "1085173079" | awk '{print strftime("%d-%b-%Y %H:%M:%S",$1)}' 21-Mai-2004 17:57:59
Outro exemplo de conversão com date
date --date='1/1/1970 + <UNIXTIME> seconds'
Converter a data 1085173079.594, execute esta linha de comando:
date --date='1/1/1970 + 1085173079 seconds'
Veja o resultado:
[zago@faqcl9 zago]$ date --date='1/1/1970 + 1085173079 seconds' Sex Mai 21 20:57:59 UTC 2004
Caso ocorra uma diferença de 3 horas é problema com a configuração do locale, no Brasil são 3 horas a menos do que o GMT, acerte isto nas configurações de fuso horario
Numerar todas as linhas de arquivo.
NF The number of fields in the current input record.
awk '{print NR" "$0}' arqorigem.txt > arqnumerado.txt
Onde $0 (zero) pega todas as linhas, qualquer numero diferente de zero pega linhas parciais do arquivo.