Brincando com vetores - complemento

Este é uma espécie de "complemento" do meu artigo anterior, sobre vetores. Neste eu apresento recursos como: utilizar a variável IFS com vetores, usar variáveis readonly, além de uma melhoria no método para passar um vetor como argumento para uma função. Espero que gostem.

[ Hits: 33.412 ]

Por: Leandro Santiago em 26/03/2007 | Blog: http://leandrosan.wordpress.com


Algumas funções que podem ser úteis



Essa é uma função que eu achei muito útil, e tem a função de criar um backup de uma variável:

$ BackupVar()
{
    eval $1[1]=\"\$$1\"
}


Como ela funciona?
É assim: de vez em quando precisamos modificar uma variável, mas restaura-la depois. Como disse no artigo anterior, uma variável comum também é um vetor, mas com somente o primeiro elemento acessado. Essa função cria uma cópia do conteúdo da variável na própria variável!

Exemplo:

$ variavel="O rato"
$ BackupVar variavel


Posso modificar a variável à vontade

$ variavel="O gato"
$ echo $variavel

O gato

Beleza.

Agora uma função que restaura o valor anterior ao "backup":

$ RestoreVar()
{
    eval $1='"${'$1'[1]}"'
    eval unset $1[1]
}


Já temos a variável variavel com o conteúdo "O gato". Restaurando ela ao valor original:

$ RestoreVar variavel
$ echo $variavel

O rato

Isso evita aquele recurso que utilizamos de usar uma variável de backup, tipo:

$ variavel_backup=$variavel

E já viu, achar nome para tanta variável pode complicar depois...

OBS: Você poderia reclamar desse negócio de usar tanta função, pois elas deixam o programa mais lento, pois o processador para a execução do programa e executa a função, etc. Não sei se há um recurso como o inline do c++, mas numa linguagem em alto nível como o shell script, não adianta ficar pensando muito em velocidade na execução, senão a gente pira! (Daqui há uns anos eu aprendo assembly e talvez pense em velocidade...).

Continuando...

No artigo anterior, eu comentei que o bash só aceita vetores unidimensionais. Disse também que não é impossível implementar, por assim dizer, uma espécie de "suporte" à vetores bidimensionais, certo?

Pois que eu tentei aqui uma destas implementações, que mostrarei adiante. Mas acontece que ela possui muitas restrições. Uma delas é que o valor atribuído não pode conter caracteres underline (_) e acento circunflexo (^), pois estes caracteres são usados internamente nas funções.

Outra limitação é a sintaxe dos comandos. Como tudo será baseado em funções, é necessário que chamemos essa função, seguida dos argumentos, que são: nomedovetor posiçãoX posiçãoY valor.

Por exemplo, Se quisermos atribuir o valor elemteste à posição Array[0,1] da matriz Array, fazemos:

$ SetElemento Array 0 1 elemteste

Confesso que não é muito prático, mas o que eu peço é: abstraia! ;)

Outra limitação neste caso é: Os elementos inseridos na "coordenada Y" devem ser inseridos ordinalmente. Explicando: não é possível inserir o elemento [1,2] antes de inserir o [1,1], assim como que não é possível inserir este sem que haja um [1,0].

Não é possível usar índices negativos - estes começam sempre em zero (0).

Mais uma é o fato de não podermos usar comandos que envolvem aritmética com esses vetores, pois tudo será feito à base de funções. Mas você pode, por exemplo, atribuir o valor de uma posição na matriz à uma variável, ou sei lá o que...

Para exibir um elemento na posição [5,3] de um vetor Array, basta:

$ EchoElemento Array 5 3

Continua não sendo muito prático, mas pra mim está de bom tamanho (por enquanto).

OBS: Deixo claro que não temos efetivamente um vetor de duas dimensões em shell. Se você tentar exibir o conteúdo de um destes vetores bidimensionais, verá que ele é um vetor comum. Nós só tratamos ele como tendo duas.

Ah, é claro, aqui vão as funções que realizam estes processos:

$ SetY() # Lista Posição Valor
{
    local IFS=^
    local VetorDirY=($1)
    VetorDirY[$2]="$3"
    echo ${VetorDirY[@]} | tr " " "^"
}


$ EchoElemento() # NomeVetor posX posY
{
    eval local ElemComEsp=\`echo '${'$1'['$2']} | cut -f'"$(($3+1))"' -d^ | tr "_" " "'\`
    echo $ElemComEsp
}


$ SetElemento() # NomeVetor posX posY valor
{
    local ElemSemEsp=`echo $4 | tr " " "_"`
    eval $1[$2]=\`SetY '${'$1'['$2']}' $3 $ElemSemEsp\`
}


Desculpem por não comentar bem as funções, mas acho que está claro o que cada comando faz.

Página anterior     Próxima página

Páginas do artigo
   1. A variável IFS
   2. Vetores read-only
   3. Passando valores por referência em funções
   4. Algumas funções que podem ser úteis
   5. Conclusão
Outros artigos deste autor

Instalando um ambiente leve e funcional em computadores antigos

Rodando vídeos .rmvb no Linux

Brincando com vetores

Ogle: O player de DVD

Recursos avançados do bash que você não aprende na escola

Leitura recomendada

Como Configurar seu Lucent Winmodem

NetProfiler - Um solução para quem passeia por várias redes

Coloque ordem em seus programas

Fazendo backup do seu MySQL com API do Dropbox

Redundância de links - Mon + Shell Script

  
Comentários
[1] Comentário enviado por removido em 27/03/2007 - 17:07h

Muito bom meu caro tenchi ;)

[2] Comentário enviado por fernandoamador em 08/04/2007 - 23:55h

Ótimo artgo...


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts