|
From: | Julio C. Neves |
Subject: | Re: [shell-script] Duvida, regex e array dinamico. |
Date: | Sat, 25 Aug 2018 14:22:24 -0300 |
Lendo um arquivo para um vetor
Ainda falando do bash 4.0, eis que ele surge com uma outra novidade: o comando intrínseco (built-in) mapfile, cuja finalidade é ler linhas da entrada primária (stdin) para dentro de um vetor indexado, sem fazer loop ou substituição de comando. Sua sintaxe é a seguinte:
mapfile [OPCS] [VETOR]
Onde os dados recebidos pela entrada primária irão para o vetor VETOR. Caso ele não seja especificado, a variável do sistema, MAPFILE, se incumbirá de receber esses dados.
As principais opções OPCS são:
Opção |
Efeito |
-n QTD |
Copia, no máximo, QTD linhas |
-O ORIGEM |
Usa ORIGEM como o menor índice de VETOR |
-s QTD |
Descarta as primeiras QTD linhas |
-c QTD |
A cada QTD linhas lidas executa o que for especificado pela opção -c |
-C COD |
Executa o código Shell especificado em COD. O índice de VETOR é adicionado ao final |
EPA! Isso deve ser muito rápido!
E é. Faça os testes e comprove! Veja só como ele funciona:
$ cat frutas Não confunda o arquivo com o vetor que usamos
abacate
maçã
morango
pera
tangerina
uva
$ mapfile vet < frutas Mandando frutas para vetor vet
$ echo ${vet[@]} Listando todos os 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 porque esse formato de read precisa receber todos os dados que serão lidos para o vetor vet. Para consertar isso poderíamos fazer:
$ read -a vet <<< $(cat frutas)
$ echo ${vet[@]}
abacate maçã morango pera tangerina uva
Mas aí a performance será pior até do que a anterior, pois também usa substituição de comandos e ainda por cima usa a instrução cat, que não é built-in.
Vejamos como funcionam as suas principais opções:
$ mapfile -n3 vet < frutas Para ler somente três linhas
$ echo ${vet[@]} Exibe os dados
abacate maçã morango
$ echo ${!vet[@]} Exibe os índices
0 1 2
$ unset vet "Mata" o vetor
$ mapfile vet < frutas Começando de novo
$ echo ${vet[@]}
abacate maçã morango pera tangerina uva
$ echo ${!vet[@]}
0 1 2 3 4 5
$ mapfile -O 6 vet < frutas Menor índice será o que já tinha mais 1
$ echo ${vet[@]}
abacate maçã morango pera tangerina uva abacate maçã morango pera tangerina uva
$ echo ${!vet[@]}
0 1 2 3 4 5 6 7 8 9 10 11
$ unset vet
$ mapfile -s 3 vet < frutas Despreza três linhas iniciais de frutas
$ echo ${vet[@]}
pera tangerina uva
$ echo ${!vet[@]}
0 1 2
$ mapfile -c1 -C"echo carreguei o índice" < frutas
carreguei o índice 0 abacate
carreguei o índice 1 maçã
carreguei o índice 2 morango
carreguei o índice 3 pera
carreguei o índice 4 tangerina
carreguei o índice 5 uva
O mesmo resultado seria obtido se fizesse:
$ mapfile -c1 -C"printf 'carreguei o índice %d %s\n'" < frutas
carreguei o índice 0
carreguei o índice 1
carreguei o índice 2
carreguei o índice 3
carreguei o índice 4
carreguei o índice 5
No entanto, poderíamos desprezar os índices, que são automaticamente lançados para a saída, se não especificarmos a máscara do printf para recebê-los (no caso %d e %s) Vamos aproveitar e tirar também o \n para não saltar muita linha. Veja:
$ mapfile -c1 -C"printf 'Carreguei o índice'" < frutas
Carreguei o índiceCarreguei o índiceCarreguei o índiceCarreguei o índiceCarreguei o índiceCarreguei o índice
Epa, isso me deu uma ideia! Posso simular uma barra de progresso rústica usando essa técnica. Vejamos:
$ mapfile -c1 -C"printf '#'" < frutas
######$
Nesses últimos exemplos, não especificamos o nome do vetor. Assim sendo, o bash mandou todos os dados para MAPFILE. Veja:
$ echo ${MAPFILE[@]}
abacate maçã morango pera tangerina uva
Isto é, foi lançado um jogo-da-velha (#) para cada elemento carregado no vetor. Isso é muito legal, mas se a quantidade de elementos for muito grande, a qualidade da apresentação será prejudicada. Para resolver isso, basta incrementar o valor da opção -c. Observe também que o prompt ficou colado na saída, sem saltar linha. Para resolver isso, o melhor é colocar um echo puro no final da linha. Vamos ver como carregar um vetor com duzentos elementos:
$ printf '%s\n' {1..200} | mapfile -c20 -C 'printf "#"'; echo
##########
Carregar um arquivo em um array?
http://wiki.softwarelivre.org/TWikiBar/TWikiBarTalkSnacks# Lendo_um_arquivo_para_um_vetor
Abraços Paulo
On 8/24/18 11:56 PM, Rodrigo Cunha address@hidden [shell-script] wrote:
> Em parte sim,na regex está perfeito, mas eu gostaria de declarar apenas um array e colocar as diferentes
> entradas em diferentes posições, mas com apenas um array.
>
>
> Em sex, 24 de ago de 2018 às 20:33, address@hidden <mailto:address@hidden.br > [shell-script]
> <address@hidden.br <mailto:shell-script@yahoogrupos.com.br >> escreveu:
>
> __
>
> Olá Rodrigo, veja se ajuda, não sei se entendi direito.
>
> i=;while read linha; do
> [[ "$linha" =~ --....-..-..\ ..:..:..-- ]] && { let i++;j=0;}
> eval vetor$i[j++]="\$linha";done < <(wget google.com <http://google.com> 2>&1)
>
> for i in ${!vetor1[*]};do echo "${vetor1[i]}";done
> --2018-08-24 20:29:57-- http://google.com/
> Resolvendo google.com <http://google.com> (google.com <http://google.com>)... 216.58.202.206,
> 2800:3f0:4001:817::200e
> Conectando-se a google.com <http://google.com> (google.com <http://google.com>)|216.58.202.206|:80...
> conectado.
> A requisição HTTP foi enviada, aguardando resposta... 301 Moved Permanently
> Localização: http://www.google.com/ [redirecionando]
>
> for i in ${!vetor2[*]};do echo "${vetor2[i]}";done
> --2018-08-24 20:29:57-- http://www.google.com/
> Resolvendo www.google.com <http://www.google.com> (www.google.com <http://www.google.com>)...
> 64.233.190.147, 64.233.190.99, 64.233.190.105, ...
> Conectando-se a www.google.com <http://www.google.com> (www.google.com
> <http://www.google.com>)|64.233.190.147|:80... conectado.
> A requisição HTTP foi enviada, aguardando resposta... 200 OK
> Tamanho: não especificada [text/html]
> Salvando em: “index.html.7”
>
> 0K .......... . 168K=0,07s
>
> 2018-08-24 20:29:58 (168 KB/s) - “index.html.7” salvo [11737]
>
> Abraços Paulo
>
> On 8/23/18 3:12 PM, Rodrigo Cunha address@hidden <mailto:rodrigo.root.rj@gmail.com >
> [shell-script] wrote:
> > Olá srs, preciso de uma ajuda.
> >
> > Quero criar um array onde o conteúdo de um stdout seja inserido automaticamente em posições diferentes.
> > No exemplo abaixo, fiz um wget para o google e retornou um texto. Quero
> > criar um array dinamico que insira dentro de cada posição todo conteudo(em string) entre este padrão
> > "--2018-08-22 16:58:04--"
> > Pretendo inserir um vetor, no array em cada padrão e captura-lo por uma Regex.
> >
> > EX:
> > Comando: #wget google.com <http://google.com> <http://google.com>
> > --2018-08-22 16:58:04-- http://google.com/
> > Resolvendo google.com <http://google.com> <http://google.com> (google.com <http://google.com>
> <http://google.com>)... 172.217.29.46,
> > 2800:3f0:4004:808::200e
> > Conectando-se a google.com <http://google.com> <http://google.com> (google.com <http://google.com>
> <http://google.com>)|172.217.29.46|:80... conectado.
> > A requisição HTTP foi enviada, aguardando resposta.... 301 Moved Permanently
> > Localização: http://www.google..com/ <http://www.google.com/> [redirecionando]
> > --2018-08-22 16:58:06-- http://www.google.com/
> > Resolvendo www.google.com <http://www.google.com> <http://www.google.com> (www.google.com
> <http://www.google.com> <http://www.google.com>)... 216.58.202.228,
> > 2800:3f0:4004:806::2004
> > Conectando-se a www.google.com <http://www.google.com> <http://www.google.com> (www.google.com
> <http://www.google.com>
> > <http://www.google.com>)|216.58.202.228|:80... conectado.
> > A requisição HTTP foi enviada, aguardando resposta.... 200 OK
> > Tamanho: não especificada [text/html]
> > Salvando em: “index.html.1”
> >
> >
> >
> > --
> > Atenciosamente,
> > Rodrigo da Silva Cunha
> > São Gonçalo, RJ - Brasil
> >
> >
> > ----------------------------------------------------------
> > Enviado por: Rodrigo Cunha <address@hidden <mailto:rodrigo.root.rj@gmail.com >>
> > ----------------------------------------------------------
>
>
>
> --
> Atenciosamente,
> Rodrigo da Silva Cunha
> São Gonçalo, RJ - Brasil
>
>
> ----------------------------------------------------------
> Enviado por: Rodrigo Cunha <address@hidden>
> ----------------------------------------------------------
[Prev in Thread] Current Thread [Next in Thread]
- Duvida, regex e array dinamico., Rodrigo Cunha, 2018/08/23
- Re: [shell-script] Duvida, regex e array dinamico., Robson Alexandre, 2018/08/24
- Re: [shell-script] Duvida, regex e array dinamico., Rodrigo Cunha, 2018/08/24
- Re: [shell-script] Duvida, regex e array dinamico., phfbettega, 2018/08/24
- Re: [shell-script] Duvida, regex e array dinamico., Rodrigo Cunha, 2018/08/24
- Re: [shell-script] Duvida, regex e array dinamico., phfbettega, 2018/08/25
- Re: [shell-script] Duvida, regex e array dinamico., Julio C. Neves <=
- Re: [shell-script] Duvida, regex e array dinamico., Robson Alexandre, 2018/08/25
- Re: [shell-script] Duvida, regex e array dinamico., Rodrigo Cunha, 2018/08/25
- Prev by Date: Fwd: [Dicas-L] INSCRIÇÕES ABERTAS: Workshop gratuito sobre Programação Shell Linux
- Next by Date: Re: [shell-script] Substituíção de cadeias com se d
- Previous by thread: Re: [shell-script] Duvida, regex e array dinamico.
- Next by thread: Re: [shell-script] Duvida, regex e array dinamico.
- Index(es):