para cada um com matriz com vários itens

0

Estou trabalhando em um script que faz o download das coisas.

No script, preciso correlacionar um nome e uma URL que serão baixados repetidamente (daí o script)

name1,url1
name2,url2
name3,url3


command $NAME $URL

Então eu quero um para cada loop que passa pela minha lista de nomes e respectivos URLs. Qual é a melhor maneira de conseguir isso? Não estou interessado neste momento em manter essas listas em um arquivo externo ou qualquer coisa assim. No script é onde eu gostaria para este exemplo.

    
por LVLAaron 11.01.2017 / 21:58

5 respostas

3

bash é bastante limitado nessa frente. Você pode querer experimentar outros shells.

Com zsh (você já está usando a sintaxe zsh porque não citou suas variáveis em command $NAME $URL ):

for name url (
  name1 url1
  name2 url2
  name3 url3
) command $name $url

Com bash ou outro shell POSIX, você poderia fazer:

while IFS=, read <&3 -r name url; do
  {
    command "$name" "$url"
  } 3<&-
done 3<< "EOF"
name1,url1
name2,url2
name3,url3
EOF

Isso significa que os valores não podem conter vírgulas ou novas linhas.

Versões recentes de bash também suportam matrizes associativas usando uma sintaxe mais parecida com a de ksh93 do que com zsh . Então, se os nomes são únicos, você poderia fazer:

typeset -A pairs
pairs=(
  [name1]=url1
  [name2]=url2
  [name3]=url3
)
for name in "${!pairs[@]}"; do
  url=${pairs[$name]}
  command "$name" "$url"
done

Isso também funcionaria em ksh93 . Cuidado com as regras de cotação variam ligeiramente entre ambos. Em zsh , a sintaxe de definição de matriz associativa é mais direta e as regras normais de cotação se aplicam:

pairs=(name1 url1 name2 url2 name3 url3)

Que você pode colocar em várias linhas:

pairs=(
  name1 url1
  name2 url2
  name3 url3
)

Tenha em atenção que a encomenda não está preservada e que bash matrizes associativas não suportam uma chave vazia.

ksh93 suporta matrizes multidimensionais, pelo que pode fazê-lo:

pairs=((name1 url1) (name2 url2) (name3 url3))
for ((i = 0; i < ${#pairs[@]}; i++)); do
  name=${pairs[i][o]} url=${pairs[i][1]}
  command "$name" "$url"
done
    
por 11.01.2017 / 22:12
1

Você pode criar um documento aqui que é gravado em um arquivo temporário e processado. O arquivo temporário será automaticamente removido, portanto, nenhuma limpeza manual é necessária.

#!/bin/bash
mylist=/var/tmp/$$
trap 'rm -f ${mylist}' EXIT
cat << _EOF_ > ${mylist}
name1 url1
name2 url2
name3,url3
_EOF_
while read name url
do
    printf "%s %s\n" ${name} ${url}
done < ${mylist}
    
por 11.01.2017 / 22:15
1

No começo eu dirijo minha mente para algo complicado como matrizes associativas.
Então percebi que isso pode ser feito tão fácil quanto abaixo, considerando que você tem tantos nomes quanto URLs:

root@debian:a=( "name1,url1" "name2,url2" "name3,url3" );while IFS="," \ 
read -r name url;do echo "command $name $url";done<<<$(printf '%s\n' "${a[@]}")
command name1 url1
command name2 url2
command name3 url3

Tudo o que você precisa é armazenar nomes e URLs no mesmo array (um no meu teste) juntos, separados, ou seja, por vírgula.

    
por 11.01.2017 / 22:43
0

Talvez um script simples funcione para você:

pairs=( "name1,url1" "name2,url2" "name3,url3" )

for pair in "${pairs[@]}"; do
    IFS=, read name url <<<"${pair}"
    printf "%s %s\n" "${name}" "${url}"
    command "${name}" "${url}"
done
    
por 12.01.2017 / 00:36
0

Um pouco complexo demais por si só, mas mantendo o formato que a maioria dos outros forneceu, mas não invocando o IFS que eu usaria

pairs=( "name1,url1" "name2,url2" "name3,url3" )

for pair in "${pairs[@]}"; do
    #Create an array in itself, of the two values.
    tmpArr=('echo $pair | tr ',' ' '')

    #Then either use Array Indexing on the array ie. 
    #Or place the offsets in their own variables. ie Run=${tmpArr[0] ...;
    command ${tmpArr[0]} ${tmpArr[1]}
done

Elimina a necessidade de Arquivos Temporários, nenhuma limpeza real necessária, desde que usada dentro de um script que os Sha-Bangs inicialmente fizeram, ou feita local em uma função, que é a maneira que eu fiz a maioria dos meus scripts, mantendo a sintaxe tão perto de 'C' quanto possível. Também adere ao meu lema bash: "Se você quer fazer, alguém já fez isso antes, e fez disso um módulo, então não faça o trabalho ..."

    
por 12.01.2017 / 20:39

Tags