shell-script-pt
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [shell-script] Script para acessar uma matriz


From: Julio C. Neves
Subject: Re: [shell-script] Script para acessar uma matriz
Date: Fri, 8 Jan 2010 11:14:19 -0200

Fala Andelnyr,
Não tive tempo de me meter na lógica do seu prg, mas deixa eu te dar algumas
dicas sobre vetores:

Estou escrevendo um artigo sobre o Bash 4.0 do qual tirei um pedaço e
transcrevo a seguir:
  Lendo um arquivo para um vetor

Ainda falando do Bash 4.0, eis que ele surge com uma outra novidade: o
comando intrínseco (*builtin*) mapfile, cuja finalidade é jogar um arquivo
de texto inteiro para dentro de um vetor, sem *loop* ou substituição de
comando

   -

   EPA! Isso deve ser muito rápido!
   -

   E é. Faça os teste e comprove!

Exemplo:

*$ cat frutas *

abacate

maçã

morango

pera

tangerina

uva

*$ mapfile vet < frutas **Mandando frutas para vetor vet*

*$ echo ${vet[@]} **Listando todos elementos de vet*

abacate maçã morango pera tangerina uva


 Obteríamos resultado idêntico se fizéssemos:

*$ vet=($(cat frutas))*


 Porém isso seria mais lento porque a substituição de comando é executada em
um *subshell*.

Uma outra forma de fazer isso que logo vem à cabeça é ler o arquivo com a
opção -a do comando read. Vamos ver como seria o comportamento disso:

*$ read -a vet < frutas *

$ echo ${vet[@]}

abacate


 Como deu para perceber, foi lido somente o primeiro registro de frutas.

Pois é, se vc está usando o Bash 4.0, poderia usar este intrínseco para
carregar o vetor. É bem mais rápido de programar e de executar.

Outra dica é que vc pode emular um array de mais de uma dimensão. No seu
caso, cada linha tem 4 campos. Supondo que a linha está em $L e o campo está
em $C, vc poderia indexar da seguinte forma:
L=3;C=2
Vet [$L$C]=110

Para recuperar, vc pode usar echo ${!Vet[@]}, que te devolverá todos e
somente os índices do vetor. Se o índice estiver em $Ind,
L=$[Ind/10]
C=$[Ind%10]

Espero que esta teoria o ajude, pq se usá-la, creio que seu prg ficará menor
e mais rápido.

Abraços,
Julio
Cursos de Shell e Zenity em 2 fins de semana?
- Em SP ligue (11)2125-4747;
- Em DF ligue (61) 3223-3000;
- Turmas fechadas em outras cidades ligue (21) 8112-9988.



2010/1/7 andelnyr <address@hidden>

>
>
> Prezados
> Sou iniciante nessa cachaça que é a programação em Shell Script e tenho
> acessado bastante as mensagens aqui do grupo e consultado tanto o livro do
> Júlio quanto o do Aurélio e tenho encontrado as respostas para a esmagadora
> maioria das minhas dúvidas.
> Recentemente comecei a desenvolver em caráter didático, melhorias em alguns
> scripts para o sistema que emprego no meu trabalho. Já estou há um pouco
> mais de um mês nisso e percebo alguma evolução, pois a cada dia que passa,
> consigo entender um pouco mais dos códigos que antes pareciam ter sido
> escritos em alguma espécie de língua morta.
> Atualmente me deparo com uma dificuldade que não consegui solucionar
> sozinho, daí decidi recorrer aos "universitários".
>
> Possuo um arquivo de texto chamado dados.txt com o seguinte conteúdo:
>
> EQP VL1 VL2 VL3
> A 100 120 150
> B 110 130 100
> C 23 45 90
>
> É uma matriz e pelo que já li o shell não trata matrizes polidimensionais,
> ficando apenas com as unidimensionais – os vetores.
> Desejo poder ler e escrever neste arquivo fornecendo linha e coluna para
> acessar os dados e escrevi o seguinte código:
>
> #Transforma de coluna para índice do vetor
> coluna2id() {
> case "$coluna" in
> "VL1") id="1" ;;
> "VL2") id="2" ;;
> "VL#") id="3" ;;
> esac
> }
>
> #Função para "pegar" um dado
> get_data() {
> linha="$1"
> coluna="$2"
> coluna2id
> while read dados
> do
> vetor_dados=( $dados )
> if [ "${vetor_dados[0]}" = "$linha" ]
> then
> echo "${vetor_dados["$id"]}"
> fi
> done < dados.txt
> }
>
> #Função para "escrever" um dado
> put_data() {
> linha="$1"
> coluna="$2"
> valor="$3"
> col2id
> while read dados
> do
> vetor_dados=( $dados )
> if [ "${vetor_dados[0]}" = "$valor" ]
> then
> vetor_dados["$id"]="$valor"
> linha_tmp="${vetor_dados[*]}"
> fi
> done < dados.txt
>
> grep -i -v "$vao" dados.txt > dados.tmp
> echo "${linha_tmp[*]}" >> dados.tmp
> mv dados.tmp dados.txt
> }
>
> Se você fizer:
> get_data A VL3 – você tem como resultado 150
>
> put_data C VL2 70 – você substitui o valor 45 pelo valor 70 no arquivo.
>
> Tudo funciona, porém este processo de leitura e escrita será realizado um
> grande número de vezes e como todo o processo de dá através de leitura e
> escrita em disco a coisa toda acaba sendo relativamente lenta – 6 ms para
> leitura e 37 ms para escrita no pior caso.
>
> Pensei em realizar estas atividades com variáveis e não com arquivos para
> evitar o grande número de operações de leitura e escrita no HD, mas já
> tentei algumas modificações e não obtive nenhum resultado.
>
> Gostaria de alguma sugestão para melhoria deste tempo de acesso.
>
> Desde já agradeço
>
>  
>


[As partes desta mensagem que não continham texto foram removidas]



reply via email to

[Prev in Thread] Current Thread [Next in Thread]