Valeu Paulo,
essa página que vc citou foi escrita por mim mas como estava sem
atualização, tirei-a do ar, mas pelo visto ainda ficou um pedacinho... ;)
Não sei se essa é a dúvida do nosso colega, pois não a li, mas de qq forma,
vou colar aqui em baixo tudo que sei sobre o cmd mapfile que é um builtin
(e portanto muito veloz) que foi inserido a partir do Bash 4.0.
Espero que seja bastante útil...
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çado
s 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*
##########
Abraços,
Julio
*» Não tem tempo para fazer um curso presencial?*
*» Na sua cidade não tem nenhum bom curso de Linux?*
*» **Conheça nosso portal educacional e estude conosco: *
* http://www.dicas-l.com.br/educacao
<http://www.dicas-l.com.br/educacao/>*
*» Treinamento presencial (em 4 sábados) no RJ e BSB *
* em http://bit.ly/cursoshelljulioneves
<http://bit.ly/cursoshelljulioneves> *
*Também damos treinamento em sua empresa*
*em qualquer cidade**, **com certificado **e nota fiscal.*
ââ
Post by ***@yahoo.com.br [shell-script]Carregar um arquivo em um array?
http://wiki.softwarelivre.org/TWikiBar/TWikiBarTalkSnacks#
Lendo_um_arquivo_para_um_vetor
Abraços Paulo
Post by Rodrigo Cunha ***@gmail.com [shell-script]Em parte sim,na regex está perfeito, mas eu gostaria de declarar apenas
um array e colocar as diferentes
Post by Rodrigo Cunha ***@gmail.com [shell-script]entradas em diferentes posições, mas com apenas um array.
__
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)
Post by Rodrigo Cunha ***@gmail.com [shell-script]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,
Post by Rodrigo Cunha ***@gmail.com [shell-script]2800:3f0:4001:817::200e
Conectando-se a google.com <http://google.com> (google.com <
http://google.com>)|216.58.202.206|:80...
Post by Rodrigo Cunha ***@gmail.com [shell-script]conectado.
A requisição HTTP foi enviada, aguardando resposta... 301 Moved
Permanently
Post by Rodrigo Cunha ***@gmail.com [shell-script]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>)...
Post by Rodrigo Cunha ***@gmail.com [shell-script]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
Post by Rodrigo Cunha ***@gmail.com [shell-script]Olá srs, preciso de uma ajuda.
Quero criar um array onde o conteúdo de um stdout seja inserido
automaticamente em posições diferentes.
Post by Rodrigo Cunha ***@gmail.com [shell-script]Post by Rodrigo Cunha ***@gmail.com [shell-script]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
uma Regex.
Post by Rodrigo Cunha ***@gmail.com [shell-script]Post by Rodrigo Cunha ***@gmail.com [shell-script]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>
Post by Rodrigo Cunha ***@gmail.com [shell-script]<http://google.com>)... 172.217.29.46,
Post by Rodrigo Cunha ***@gmail.com [shell-script]2800:3f0:4004:808::200e
Conectando-se a google.com <http://google.com> <http://google.com> (
google.com <http://google.com>
Post by Rodrigo Cunha ***@gmail.com [shell-script]<http://google.com>)|172.217.29.46|:80... conectado.
Post by Rodrigo Cunha ***@gmail.com [shell-script]A requisição HTTP foi enviada, aguardando resposta.... 301 Moved
Permanently
[redirecionando]
http://www.google.com> (www.google.com
Post by Rodrigo Cunha ***@gmail.com [shell-script]<http://www.google.com> <http://www.google.com>)... 216.58.202.228,
Post by Rodrigo Cunha ***@gmail.com [shell-script]2800:3f0:4004:806::2004
Conectando-se a www.google.com <http://www.google.com> <
http://www.google.com> (www.google.com
Post by Rodrigo Cunha ***@gmail.com [shell-script]<http://www.google.com>
Post by Rodrigo Cunha ***@gmail.com [shell-script]<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
----------------------------------------------------------
----------------------------------------------------------
--
Atenciosamente,
Rodrigo da Silva Cunha
São Gonçalo, RJ - Brasil
----------------------------------------------------------
----------------------------------------------------------