Professional Documents
Culture Documents
�����������������������������������������������������������������������������������������������������������������������������������������������������
Papo de Botequim LINUX USER
Papo de
botequim III
Um chopinho, um aperitivo e o papo continua. Desta vez vamos aprender
alguns comandos de manipulação de cadeias de caracteres, que serão muito
é usado para cortar um determinado circunflexo (^) do resto do registro, que Para entender melhor isso, vamos anali-
pedaço de um arquivo. A sintaxe e é formado por diversos grupos compos- sar a primeira linha de musicas:
alguns exemplos de uso podem ser vis- tos pelo intérprete de cada música do
tos no Quadro 1: CD e a respectiva música interpretada. $ head -1 musicas
Como dá para ver, existem quatro Estes grupos são separados entre si por album 1^Artista1~Musica1: U
sintaxes distintas: na primeira (-c 1-5) dois-pontos (:) e o intérprete será sepa- Artista2~Musica2
especifiquei uma faixa, na segunda rado do nome da música por um til (~).
(-c -6) especifiquei todo o texto até Então, para pegar os dados referentes Então observe o que foi feito:
uma posição, na terceira (-c 4-) tudo de a todas as segundas músicas do arquivo
uma determinada posição em diante e musicas, devemos digitar: album 1^Artista1~Musica1: U
na quarta (-c 1,3,5,7,9), só as posições Artista2~Musica2
determinadas. A última possibilidade $ cut -f2 -d: musicas
(-c -3,5,8-) foi só para mostrar que pode- Artista2~Musica2 Desta forma, no primeiro cut o primeiro
mos misturar tudo. Artista4~Musica4 campo do delimitador (-d) dois-pon-
Mas não pense que acabou por aí! Artista6~Musica5 tos (:) é album 1^Artista1~Musica1 e o
Como você deve ter percebido, esta Artista8~Musica8@10_L: segundo, que é o que nos interessa, é
forma de cut é muito útil para lidar com Artista2~Musica2. Vamos então ver o
arquivos com campos de tamanho fi xo, Ou seja, cortamos o segundo campo que aconteceu no segundo cut:
mas atualmente o que mais existe são z(-f de field, campo em inglês) delimi-
arquivos com campos de tamanho vari- tado (-d) por dois-pontos (:). Mas, se Artista2~Musica2
ável, onde cada campo termina com um quisermos somente os intérpretes, deve-
delimitador. Vamos dar uma olhada no mos digitar: Agora, primeiro campo do delimitador
arquivo musicas que começamos a pre- (-d) til (~), que é o que nos interessa,
parar na última vez que viemos aqui no $ cut -f2 -d: musicas | cut U é Artista2 e o segundo é Musica2. Se
botequim. Veja o Quadro 2. -f1 -d~ o raciocínio que fizemos para a pri-
�����������������������������
www.linuxmagazine.com.br Outubro 2004 85
��������������������������������������������������������������������������������
���������������������������������������������������
����������������������������������������������������������������������������������������������������������������������������������������������������
LINUX USER Papo de Botequim
$ tr A-Z a-z < ArqEnt > / tmp/$$ $ tr ”;” ”\012” < confuso
Quadro 2 – O arquivo $ mv -f /tmp/$$ ArqEnt
musicas Agora veja a diferença entre o resultado
Note que neste caso usei a notação A- de um comando date executado hoje e
Z para não escrever ABCD…YZ. Outro outro executado há duas semanas:
$ cat musicas
tipo de notação que pode ser usada são
album 1^Artista1~Musica1:U
as escape sequences (como eu traduzi- Sun Sep 19 14:59:54 2004
Artista2~Musica2
ria? Seqüências de escape? Meio sem Sun Sep 5 10:12:33 2004
album 2^Artista3~Musica3:U
sentido, né? Mas vá lá…) que também
Artista4~Musica4
são reconhecidas por outros comandos Notou o espaço extra após o “Sep” na
album 3^Artista5~Musica5:U
e também na linguagem C, e cujo signi- segunda linha? Para pegar a hora eu
Artista6~Musica5
ficado você verá na Tabela 2: deveria digitar:
album 4^Artista7~Musica7:U
Deixa eu te contar um “causo”: um
Artista8~Musica8
aluno que estava danado comigo resol- $ date | cut -f 4 -d ’ ’
veu complicar minha vida e como res- 14:59:54
�����������������������������
86 Outubro 2004 www.linuxmagazine.com.br
��������������������������������������������������������������������������������
����������������������������������������������������
�����������������������������������������������������������������������������������������������������������������������������������������������������
Papo de Botequim LINUX USER
Mas há duas semanas ocorreria o Bem a opção -d do tr remove do arquivo E veja também o date:
seguinte: todas as ocorrências do caractere espe-
cificado. Desta forma eu removi os $ date
$ date | cut -f 4 -d ’ ’ caracteres indesejados, salvei o texto Mon Sep 20 10:47:19 BRT 2004
5 em um arquivo temporário e posterior-
mente renomeei-o para o nome original. Repare que o mês e o dia estão no
Isto porque existem 2 caracteres em Uma observação: em um sistema Unix mesmo formato em ambos os coman-
branco antes do 5 (dia). Então o ideal eu deveria digitar: dos. Ora, se em algum registro do who
seria transformar os espaços em branco eu não encontrar a data de hoje, é sinal
consecutivos em somente um espaço $ tr -d ’\015’ < ArqDoDOS.U que o usuário está “logado” há mais
para poder tratar os dois resultados do txt > /tmp/$$ de um dia, já que ele não pode ter se
comando date da mesma forma, e isso “logado” amanhã… Então vamos guar-
se faz assim: Uma dica: o problema com os termina- dar o pedaço que importa da data de
dores de linha (CR/LF) só aconteceu hoje para depois procurá-la na saída do
$ date | tr -s ” ” porque a transferência do arquivo foi comando who:
Sun Sep 5 10:12:33 2004 feita no modo binário (ou image), Se
antes da transmissão do arquivo tivesse $ Data=$(date | cut -f 2-3 U
E agora eu posso cortar: sido estipulada a opção ascii do ftp, isto -d’ ’)
não teria ocorrido.
$ date | tr -s ” ” | cut -f 4 U – Olha, depois desta dica tô começando a Eu usei a construção $(...), para prio-
-d ” ” gostar deste tal de shell, mas ainda tem rizar a execução dos comandos antes
10:12:33 muita coisa que não consigo fazer. de atribuir a sua saída à variável Data.
– Pois é, ainda não te falei quase nada Vamos ver se funcionou:
Olha só como o Shell está quebrando o sobre programação em shell, ainda
galho. Veja o conteúdo de um arquivo tem muita coisa para aprender, mas $ echo $Data
baixado de uma máquina Windows: com o que aprendeu, já dá para resol- Sep 20
ver muitos problemas, desde que você
$ cat -ve ArqDoDOS.txt adquira o “modo shell de pensar”. Você Beleza! Agora, o que temos que fazer é
Este arquivo^M$ seria capaz de fazer um script que diga procurar no comando who os registros
foi gerado pelo^M$ quais pessoas estão “logadas” há mais que não possuem esta data.
DOS/Win e foi^M$ de um dia no seu servidor?
baixado por um^M$ – Claro que não! Para isso seria necessá- – Ah! Eu acho que estou entendendo!
ftp mal feito.^M$ rio eu conhecer os comandos condicio- Você falou em procurar e me ocorreu o
nais que você ainda não me explicou comando grep, estou certo?
Dica: a opção -v do cat mostra os carac- como funcionam. - Deixa eu tentar – Certíssimo! Só que eu tenho que usar o
teres de controle invisíveis, com a nota- mudar um pouco a sua lógica e trazê- grep com aquela opção que ele só lista
ção ^L, onde ^ é a tecla Control e L é la para o “modo shell de pensar”, mas os registros nos quais ele não encon-
a respectiva letra. A opção -e mostra o antes é melhor tomarmos um chope. trou a cadeia. Você se lembra que
fi nal da linha como um cifrão ($). Agora que já molhei a palavra, vamos opção é essa?
Isto ocorre porque no DOS o fi m dos resolver o problema que te propus. Veja – Claro, a -v…
registros é indicado por um Carriage como funciona o comando who: – Isso! Tá ficando bom! Vamos ver:
Return (\r – Retorno de Carro, CR) e
um Line Feed (\f – Avanço de Linha, ou $ who $ who | grep -v ”$Data”
LF). No Linux porém o fi nal do regis- jneves pts/ U jneves pts/ U
tro é indicado somente pelo Line Feed. 1 Sep 18 13:40 1 Sep 18 13:40
Vamos limpar este arquivo: rtorres pts/ U
0 Sep 20 07:01 Se eu quisesse um pouco mais de perfu-
$ tr -d ’\r’ < ArqDoDOS.txt > /tmp/$$ rlegaria pts/ U maria eu faria assim:
$ mv -f /tmp/$$ ArqDoDOS.txt 1 Sep 20 08:19
lcarlos pts/ U $ who | grep -v ”$Data” |U
Agora vamos ver o que aconteceu: 3 Sep 20 10:01 cut -f1 -d ’ ’
jneves
$ cat -ve ArqDoDOS.txt Tabela 1 – O comando tr
Este arquivo$ Opção Significado Viu? Não foi necessário usar comando
foi gerado pelo$ condicional, até porque o nosso
-s Comprime n ocorrências de
DOS/Rwin e foi$ cadeia1 em apenas uma
comando condicional, o famoso if, não
baixado por um$ testa condição, mas sim instruções.
-d Remove os caracteres de cadeia1
ftp mal feito.$ Mas antes veja isso:
�����������������������������
www.linuxmagazine.com.br Outubro 2004 87
��������������������������������������������������������������������������������
���������������������������������������������������
����������������������������������������������������������������������������������������������������������������������������������������������������
LINUX USER Papo de Botequim
�����������������������������
88 Outubro 2004 www.linuxmagazine.com.br
��������������������������������������������������������������������������������
����������������������������������������������������
�����������������������������������������������������������������������������������������������������������������������������������������������������
Papo de Botequim LINUX USER
Lembra que eu falei que ao longo dos no início da cadeia e cifrão ($) no fi m, Como você viu, o programa melho-
nossos papos e chopes os nossos pro- servem para testar se o parâmetro (o rou um pouquinho, mas ainda não está
gramas iriam se aprimorando? Então álbum e seus dados) é exatamente igual pronto. À medida que eu te ensinar a
vejamos agora como podemos melhorar a algum registro já existente. Vamos programar em shell, nossa CDteca vai
o nosso programa para incluir músicas executar nosso programa novamente, ficar cada vez melhor.
na "CDTeca": mas desta vez passamos como parâme- – Entendi tudo que você me explicou,
tro um álbum já cadastrado, pra ver o mas ainda não sei como fazer um if
$ cat musinc que acontece: para testar condições, ou seja o uso
#!/bin/bash normal do comando.
# Cadastra CDs (versao 3) $ musinc ”album 4^Artista7~ U – Para isso existe o comando test, que
# Musica7:Artista8~Musica8” testa condições. O comando if testa
if grep ”^$1$” musicas > U Este álbum já está cadastrado o comando test. Como já falei muito,
/dev/null preciso de uns chopes para molhar a
then E agora um não cadastrado: palavra. Vamos parar por aqui e na
echo Este álbum já está U próxima vez te explico direitinho o
cadastrado $ musinc ”album 5^Artista9~ U uso do test e de diversas outras sinta-
else Musica9:Artista10~Musica10” xes do if.
echo $1 >> musicas $ cat musicas – Falou! Acho bom mesmo porque eu
sort musicas -o musicas album 1^Artista1~Musica1: U também já tô ficando zonzo e assim
fi Artista2~Musica2 tenho tempo para praticar esse monte
album 2^Artista3~Musica3: U de coisas que você me falou hoje.
Como você viu, é uma pequena evolu- Artista4~Musica4 Para fi xar o que você aprendeu, tente
ção em relação à versão anterior. Antes album 3^Artista5~Musica5: U fazer um scriptizinho para informar se
de incluir um registro (que na versão Artista6~Musica5 um determinado usuário, cujo nome
anterior poderia ser duplicado), testa- album 4^Artista7~Musica7: U será passado como parâmetro, está
mos se o registro começa (^) e termina Artista8~Musica8 “logado” no sistema ou não.
($) de forma idêntica ao parâmetro album 5^Artista9~Musica9: U – Aê Chico! traz mais dois chopes pra
álbum passado ($1). O circunflexo (^) Artista10~Musica10 mim por favor… ■
�����������������������������
www.linuxmagazine.com.br Outubro 2004 89
��������������������������������������������������������������������������������