Não, não vou falar de como combater o mosquito da dengue. Vou falar um pouco de vetores, que até há algum tempo atrás eu nem sabia que existiam em shell. Espero que vocês fiquem tão impressionados quanto fiquei!
Podemos usar aqueles truques de lógica e matemática (>,<,&&,&,||,++,--,etc) com elementos de um vetor também.
Exemplos:
Primeiro, criaremos um vetor com elementos numéricos:
$ SEQ=($(seq 0 2 10)) # Seis primeiros pares $ echo ${SEQ[@]}
0 2 4 6 8 10
Agora, por exemplo, incrementamos o elemento SEQ[4]:
$ ((SEQ[4]++))
E atribuímos o valor SEQ[1]**3 ("ao cubo") ao elemento SEQ[1]:
$ ((SEQ[1]=SEQ[1]**3))
Exibindo o vetor:
$ echo ${SEQ[@]}
0 8 4 6 9 10
Somando dois elementos de um vetor:
$ Soma=$((SEQ[1]+SEQ[2]))
Usando condicionais:
Se o primeiro elemento de SEQ é zero:
$ ((SEQ==0)) && echo ${SEQ} é igual a zero
0 é igual a zero
Se o elemento de índice 4 de SEQ é positivo (ou menor que zero):
$ ((SEQ[4]>=0)) && echo ${SEQ[4]} é positivo || echo ${SEQ[4]} é negativo
9 é positivo
Um exemplo prático:
#!/bin/bash
# Script que diz quantos números negativos, positivos e neutros há num vetor
vetor=(-1 -5 5 6 -10 3 8 9 0) # Inicializo o vetor
# Inicializo algumas variáveis
negativo=0
positivo=0
neutro=0
Tamanho=${#vetor[@]} # Tamanho guarda o número de elementos de "vetor"
for ((i=0;i<Tamanho;i++))
do
if ((vetor[i]>0)); then ((positivo++))
elif ((vetor[i]<0)); then ((negativo++))
else ((neutro++)); fi
done
echo "Em vetor existem $positivo números positivos, $negativo negativos e $neutro neutros."
Executando, teremos a seguinte saída na tela.
Em vetor existem 5 números positivos, 3 negativos e 1 neutros.
Estes foram somente exemplos mais simples. Há muito mais recursos lógico-aritméticos que podem ser usados em shell script. Há, inclusive, muitos artigos e dicas muito bons aqui mesmo no VOL que ensinam a usar estes recursos.
[1] Comentário enviado por tenchi em 23/01/2007 - 10:28h
Ae pessoal, eu esqueci de falar que, para que as operações funcionem corretamente, é preferível que os elementos do vetor não contenham o caractere espaço ' '.
Mas como isso pode ser feito? Basicamente substituindo o espaço por um caractere, como o underline (_).
Por exemplo, se os elementos de um vetor forem lidos pelo usuário:
(...)
indice=0
while <alguma coisa>
do
read elemento
vetor[$indice]=`echo $elemento | tr ' ' '_'`
let indice++
done
(...)
Assim, a string "O rato roeu a roupa" estará dentro do vetor da seguinte forma: "O_rato_roeu_a_roupa".
E quando formos ler o valor de um elemento, fazemos o seguinte:
echo ${vetor[$i]} | tr '_' ' '
Bem, espero que não se incomodem pela minha falta de atenção, pois sem esse negócio de substituir o espaço, um elemento "alguma coisa" logo viraria dois elementos: "alguma" e "coisa", o que seria um erro brutal.
E para passar um vetor por referencia, usamos o comando eval, que é muito útil.
Com ele, nos referirmos à um vetor não como ${vetor1[@]}, mas como vetor1 somente, o que acaba com aquele desperdício de processamento que eu comentei. Por exemplo, vou reescrever as funções Invert e quant que citei acima:
function quant
{
local negativo=0
local positivo=0
local neutro=0
eval 'local Tamanho=${#'$1'[@]}'
eval 'for ((i=0;i<Tamanho;i++))
do
if (('$1'[i]>0)); then ((positivo++))
elif (('$1'[i]<0)); then ((negativo++))
else ((neutro++)); fi
done'
echo "$negativo:$neutro:$positivo"
}
Usando:
$ Nomes=(ana beto carlos daniel)
$ echo ${Nomes[@]}
ana beto carlos daniel
$ Invert Nomes
$ echo ${Nomes[@]}
daniel carlos beto ana
Sei que assim as coisas ficam bem confusas, mas eu ainda estou procurando um jeito de melhorar isso tudo. E uma hora ou outra as coisas ficam confusas, não é?
[4] Comentário enviado por dailson em 23/01/2007 - 16:02h
Aproveitando o artigo de vetores, alguém sabe informar porque a variável $STRING no laço não funciona... ou melhor, ela é carregad, mas o sed não faz o que deveria fazer??
PALAVRAS=("google" "googleadservices" "atdmt")
TAMANHO_VETOR=`echo ${PALAVRAS[*]} | wc -w`
# Subtraio uma posicao do tamanho, pois o vetor começa na posicao 0 (zero)
let TAMANHO_VETOR--
# Limpeza
for i in `seq 0 $TAMANHO_VETOR`
do
STRING=`echo ${PALAVRAS[$i]}`
sed -n '/$STRING/!p' /etc/squid/hosts.txt > /etc/squid/hosts.txt.temp
mv /etc/squid/hosts.txt.temp /etc/squid/hosts.txt
done
[5] Comentário enviado por tenchi em 23/01/2007 - 16:55h
Hum... dailson, primeiramente, valew pelos comentários...
Segundo, acho que o seu sed não está funcionando pois o nome $STRING não está sendo substituido pelo conteúdo dele. Por causa das aspas simples...
Tente usar as aspas duplas..
Ou depure o seu script.
Faça o seguinte:
$ bash -xv script.sh
Assim é possível ver aonde está o erro.
Acredite, esse negócio de depurar programas é uma tremenda mão na roda.
Veja a saída do comando que vc vai saber o que cada coisa faz...
[7] Comentário enviado por linus black em 23/01/2007 - 17:38h
gostei mas eu estou com uma duvida cruel!!!
eu poderia por ex: criar anexando caminhos de icones as strings para automatizar a execução do script com entesão de criar um programa baseado nesta explanação. e como posso proceder.. 10 Já fiquei fãn deste cara...
[8] Comentário enviado por dailson em 24/01/2007 - 10:13h
Oi Tenchi
Na variável STRING não estou usando aspas e sim acento grave ` `
Mas o problema não estava ai e sim nas aspas do sed, quando retirei as aspas tudo funcionou normalmente!!!
Valeu a dica da depuração!!!!
E mais uma vez, parabéns!!
[9] Comentário enviado por tenchi em 24/01/2007 - 21:43h
Então dailson, era dessas que eu tava falando! rss.
Foi mal, é que eu não sou muito bom nesse negócio de expressões regulares...
"Essas expressões regulares ainda vão me matar do coração"