Usando o comando AWK

O AWK ? um filtro no qual possui uma linguagem pr?pria no qual o torna muito mais que um simple comando para filtragem de conte?do.

Neste tutorial irei exemplificar algumas das t?cnicas de filtragem assim como o significado de cada flag de comando.

Exemplo 1)

Imagine que voc? queira criar uma lista com todos os usu?rio ativos em seu sistema e voc? precisar? dos nomes dos usu?rio e os UID e GID respectivamente, para isso usaremos o comando AWK para filtrar os devidos campos:

cat /etc/passwd |awk -F: ‘{ print $1 “:” $3}’

No caso acima usamos o comando cat para lista o conte?do do arquivo /etc/passwd e redirecionando a sa?da para o comando AWK atrav? do caractere pipe.

-F: = onde -F: especifica que o caractere “:” ? servir? como caracter separador

‘{ print $1 “:” $3}’ = aqui estamos especificando que o comando “print” imprima os primeiros “$1″ argumentos da sa?da padr?o, os “$3″ terceiros e usando como separador de conte?do o caractere “:”.

Exemplo 2)

Neste segundo exemplo iremos filtrar a saida do comando ps -aef especificando qual processo cada usu?rio esta executando em nosso SO.

ps -aef | awk ‘{ print “Usuario: ” $1 ” PID: ” $2 ” processos: ” $8 }’

Neste exemplo usamos o AWK para filtrar a sa?da padr?o do comando ps -aef especificando para que ele imprima os campos 1,2 e 8 adicionando os coment?rios entre eles.

Exemplo 3)

Os par?metros “NF” e “NR” possuem algumas particularidades onde:

NF = possibilita sabermos quantos campos cada linha ser? classificada, veja o exemplo abaixo:

awk -F: ‘{ print NF}’ /etc/passwd |tail -n1

com o comando acima podemos descobrir que o arquivo /etc/passwd ser? classificado em 7 campos utilizando o caracter separador “:”

NR = par?metro usado para imprimir p n?mero da linha ou da sa?da, veja o exemplo:

ls | awk ‘{ print NR “: ” $0}’

aqui criamos uma listagem de diret?rio numerada usando o par?metro NR.

Exemplo 4)

Outra funcionalidade do AWK ? criar vari?veis de comando podendo acumular valores dos dados passados, no exemplo abaixo iremos calcular a quantidade de blocos que nosso disco r?gido possui:

df | awk ‘{ total = total + $2; print total}’

A variav?l total receber? o valor dela acumulado do segundo campo do comando “df” que corresponde a quantidade de blocos do disco.

Este s?o apenas alguns exemplos simples que este poderoso comando pode executar mais informa??es poderam ser encontrados com o comando man ou info.

Espero que tenham aproveitado,

at? a pr?xima

Numerando arquivos de um diret?rio

cat -n <(ls)

Usando o comando tail

Uma das grandes fun??es do comando tail ? usar para verificar a sa?da padr?o de comandos e aplicativos em tempo real

exemplo

tail -f |ps -aef

com este comando voc? poderia verificar em tempo real todos os processos que est?o acontecendo na m?quina.

Usando o XARGS

Este artigo foi adquirido pelo site Dicas-L da Unicamp

Colabora??o: J?lio Neves

Apesar de hoje ser dia de praia/piscina e cerveja gelada, vou pegar pesado porque a nossa semana de dicas est? acabando e eu n?o poderia deixar de mostrar as op??es e seus respectivos usos do comando xargs.

Existe um comando, cuja fun??o primordial ? construir listas de par?metros e pass?-la para a execu??o de outros programas ou instru??es. Este comando ? o xargs e deve ser usado da seguinte maneira:

xargs [comando [argumento inicial]]

Caso o comando, que pode ser inclusive um script Shell, seja omitido, ser? usado por default o echo.

O xargs combina o argumento inicial com os argumentos recebidos da entrada padr?o, de forma a executar o comando especificado uma ou mais vezes.

Exemplo:

Vamos produrar em todos os arquivos abaixo de um determinado diret?rio uma cadeia de caracteres usando o comando find com a op??o type f para pesquisar somente os arquivos normais, desprezando diret?rios, arquivos especiais, arquivos de liga??es, etc, e vamos torn?-la mais gen?rica recebendo o nome do diret?rio inicial e a cadeia a ser pesquisada como par?metros. Para isso fazemos:

$ cat grepr
#
# Grep recursivo
# Pesquisa a cadeia de caracteres definida em $2 a partir do diretorio $1
#
find $1 -type f -print|xargs grep -l “$2″

Na execu??o deste script procuramos, a partir do diret?rio definido na vari?vel $1, todos os arquivos que continham a cadeia definida na vari?vel $2.

Exatamente a mesma coisa poderia ser feito se a linha do programa fosse a seguinte:

find $1 -type f -exec grep -l “$2″ {} \;

Este processo tem duas grandes desvantagens sobre o anterior:

1. A primeira ? bastante vis?vel: o tempo de execu??o deste m?todo ? muito superior ao daquele, isso porque o grep ser? feito em cada arquivo que lhe for passado pelo find, um-a-um, ao passo que com o xargs, ser? passada toda, ou na pior das hip?teses, a maior parte poss?vel, da lista de arquivos gerada pelo find;

2. Dependendo da quantidade de arquivos encontrados que atendem ao find, poderemos ganhar aquela famosa e fat?dica mensagem de erro “Too many arguments” indicando um estouro da pilha de execu??o do grep. Como foi dito no item anterior, se usarmos o xargs ele passar? para o grep a maior quantidade de par?metros poss?vel, suficiente para n?o causar este erro, e caso necess?rio executar? o grep mais de uma vez.

ATEN??O! A? pessoal do linux que usa o ls colorido que nem porta de tinturaria: nos exemplos a seguir que envolvem esta instru??o, voc? devem usar a op??o –color=none, sen?o existem grandes chances dos resultados n?o ocorrerem como o esperado.

Vamos agora analisar um exemplo que ? mais ou menos o inverso deste que acabamos de ver. Desta vez, vamos fazer um script para remover todos os arquivos do diret?rio corrente, pertencentes a um determinado usu?rio.

A primeira id?ia que surge ?, como no caso anterior, usar um comando find, da seguinte maneira:

$ find . -user cara -exec rm -f {} \;

Quase estaria certo, o problema ? que desta forma voc? removeria n?o s? os arquivos do cara no diret?rio corrente, mas tamb?m de todos os outros subdiret?rios “pendurados” neste. Vejamos ent?o como fazer:

$ ls -l | grep ” cara ” | cut -c55- | xargs rm

Desta forma, o grep selecionou os arquivos que continham a cadeia cara no diret?rio corrente listado pelo ls -l. O comando cut pegou somente o nome dos arquivos, passando-os para a remo??o pelo rm usando o comando xargs como ponte.

mais xargs

Colabora??o: J?lio Neves

Continuamos hoje o que come?amos ontem, isto ?, a ver as facilidades oferecidas pelo comando xargs.

O xargs ? tamb?m uma excelente ferramenta de cria??o de one-liners (scripts de somente uma linha). Veja este para listar todos os donos de arquivos (inclusive seus links) “pendurados” no diret?rio /bin e seus subdiret?rios.

$ find /bin -type f -follow | \
xargs ls -al | tr -s ‘ ‘ | cut -f3 -d’ ‘ | sort -u

Muitas vezes o /bin ? um link (se n?o me engano, no Solaris o ?) e a op??o -follows obriga o find a seguir o link. O comando xargs alimenta o ls -al e a seq??ncia de comandos seguinte ? para pegar somente o 3? campo (dono) e classific?-lo devolvendo somente uma vez cada dono (op??o -u do comando sort).

Voc? pode usar as op??es do xargs para construir comandos extremamente poderosos. Para exemplificar isso e come?ar a entender as principais op??es desta instru??o, vamos supor que temos que remover todos as arquivos com extens?o .txt sob o diret?rio corrente e apresentar os seus nomes na tela. Veja o que podemos fazer:

$ find . -type f -name “*.txt” | \
xargs -i bash -c “echo removendo {}; rm {}”

A op??o -i do xargs troca pares de chaves ({}) pela cadeia que est? recebendo pelo pipe (|). Ent?o neste caso as chaves ({}) ser?o trocadas pelos nomes dos arquivos que satifa?am ao comando find.

Olha s? a brincadeira que vamos fazer com o xargs:

$ ls | xargs echo > arq.ls
$ cat arq.ls
arq.ls arq1 arq2 arq3
$ cat arq.ls | xargs -n1
arq.ls
arq1
arq2
arq3

Quando mandamos a sa?da do ls para o arquivo usando o xargs, comprovamos o que foi dito anteriormente, isto ?, o xargs manda tudo que ? poss?vel (o suficiente para n?o gerar um estouro de pilha) de uma s? vez. Em seguida, usamos a op??o -n 1 para listar um por vez. S? para dar certeza veja o exemplo a seguir, quando listaremos dois em cada linha:

$ cat arq.ls | xargs -n 2
arq.ls arq1
arq2 arq3

Mas a linha acima poderia (e deveria) ser escrita sem o uso de pipe (|), da seguinte forma:

$ xargs -n 2 < arq.ls

Outra op??o legal do xargs ? a -p, na qual o xargs pergunta se voc? realmente deseja executar o comando. Digamos que em um diret?rio voc? tenha arquivo com a extens?o .bug e .ok, os .bug est?o com problemas que ap?s corrigidos s?o salvos como .ok. D? uma olhadinha na listagem deste diret?rio:

$ ls dir
arq1.bug
arq1.ok
arq2.bug
arq2.ok

arq9.bug
arq9.ok

Para comparar os arquivos bons com os defeituosos, fazemos:

$ ls | xargs -p -n2 diff -c
diff -c arq1.bug arq1.ok ?…y
….
diff -c arq9.bug arq9.ok ?…y

Para finalizar, o xargs tamb?m tem a op??o -t, onde vai mostrando as instru??es que montou antes de execut?-las. Gosto muito desta op??o para ajudar a depurar o comando que foi montado.

Ent?o podemos resumir o comando de acordo com a tabela a seguir:

Op??o A??o

-i Substitui o par de chaves ({}) pelas cadeias recebidas
-nNum Manda o m?ximo de par?metros recebidos, at? o m?ximo de Num para o comando a ser executado
-lNum Manda o m?ximo de linhas recebidas, at? o m?ximo de Num para o comando a ser executado
-p Mostra a linha de comando montada e pergunta se deseja execut?-la
-t Mostra a linha de comando montada antes de execut?-la

Duvidas? julio.neves@gmail.com
Deseja fazer curso de Programa??o em Shell? julio.neves@tecnohall.com.br

O Comando Paste

Colabora??o: J?lio Neves

O paste ? um comando pouco usado por sua sintaxe ser pouco
conhecida. Vamos brincar com 2 arquivos criados da seguinte
forma:

$ seq 10 > inteiros
$ seq 2 10 > pares

Para ver o conte?do dos arquivos criados, vamos usar o paste
na sua forma careta:

$ paste inteiros pares
1 2
2 4
3 6
4 8
5 10
6
7
8
9
10

Agora vamos transformar a coluna do pares em linha:

$ paste -s pares
2 4 6 8 10

O separador default ? , mas isso pode ser alterado com
a op??o -d. Ent?o para calcular a soma do conte?do de pares
primeiramente far?amos:

$ paste -s -d’+’ pares # tamb?m poderia ser -sd’+’
2+4+6+8+10

e depois passar?amos esta linha para a calculadora (bc)
e ent?o ficaria:

$ paste -s -d’+’ pares | bc
30

Assim sendo, para calcular o fatorial do n?mero contido em
$Num, basta:

$ seq $Num | paste -sd’*’ | bc

At? amanh?…

Substitui??o de Processos

Colabora??o: J?lio Neves

Ontem aqui apareceu uma dica sobre named pipes, hoje vou mostrar que o Shell tamb?m usa os named pipes de uma maneira bastante singular, que ? a substitui??o de processos (process substitution). Uma substitui??o de processos ocorre quando voc? p?e um < ou um > grudado na frente do par?ntese da esquerda. Teclando-se o comando:

$ cat < (ls -l)

Resultar? no comando ls -l executado em um subshell como ? normal, por?m redirecionar? a sa?da para um named pipe tempor?rio, que o Shell cria, nomeia e depois remove. Ent?o o cat ter? um nome de arquivo v?lido para ler (que ser? este named pipe e cujo dispositivo l?gico associado ? /dev/fd/63), e teremos a mesma sa?da que a gerada pela listagem do ls -l, por?m dando um ou mais passos que o usual.

Como poderemos constatar isso? F?cil… Veja o comando a seguir:

$ ls -l >(cat)
l-wx—— 1 jneves jneves 64 Aug 27 12:26 /dev/fd/63 -> pipe:[7050]

?… Realmente ? um named pipe.

Voc? deve estar pensando que isto ? uma maluquice de nerd, n?? Ent?o suponha que voc? tenha 2 diret?rios: dir e dir.bkp e deseja saber se os dois est?o iguais (aquela velha d?vida: ser? que meu backup est? atualizado?). Basta comparar os dados dos arquivos dos diret?rios com o comando cmp, fazendo:

$ cmp < (cat dir/*) <(cat dir.bkp/*) || echo backup furado

ou, melhor ainda:

$ cmp <(cat dir/*) <(cat dir.bkp/*) >/dev/null || echo backup furado

Este ? um exemplo meramente did?tico, mas s?o tantos os comandos que produzem mais de uma linha de sa?da, que serve como guia para outros. Eu quero gerar uma listagem dos meus arquivos, numerando-os e ao final dar o total de arquivos do diret?rio corrente:

while read arq
do
((i++)) # assim nao eh necessario inicializar i
echo “$i: $arq”
done < <(ls)
echo “No diretorio corrente (`pwd`) existem $i arquivos”

T? legal, eu sei que existem outras formas de executar a mesma tarefa. Mas tente fazer usando while, sem usar substitui??o de processos que voc? ver? que este m?todo ? muito melhor.

At? amanh?…

Duvidas? julio.neves@gmail.com
Deseja fazer curso de Programa??o em Shell? julio.neves@tecnohall.com.br

Comandos para ger?nciamento de processos

PSTREE

O comando Pstree assim como o comando ( ps ) t?m a fun??o de listar processos, a diferen?a ? que o Pstree lista os processos de forma mais organizada como uma ?rvore de processos e suas ramifica??es dos processos filhos.

Segue abaixo um exemplo de sintaxe de comando:

#pstree -aGhp

Entendendo as flags

-a: Exibe os argumentos de linha de comando dos processos listados
-G: Muda o padr?o do tra?o de caracteres para o padr?o VT100
-h: Destaca o processo atualmente lista e seus ancestrais
-p: exibe o PID dos processos

A id?ia b?sica do comando j? foi passado agora caso queira mais informa??es use o Man Page do comando.

PIDOF

O comando pidof exibe uma lista dos PID’s dos processos atualmente em execu??o

Olhe o exemplo abaixo:

Digamos que voc? queira saber os PID’s do processos do ger?nciador de janelas KDE:

#pidof -x kdeinit

a sa?da seria a lista dos processos iniciados pelo kdeinit