variable_list="
any:any:-a -b -c any
one:one:-c -b -f -m mul
mul:one:-c -b -f -m mul
"
for f in `echo $variable_list`
do
c1=`echo $f | cut -d':' -f1`;
c2=`echo $f | cut -d':' -f2`;
c3=`echo $f | cut -d':' -f3-`;
echo "c1==>$c1 and c2==>$c2 and c3==>$c3";
#exit 0; ###I made mistake here
done;
Saída esperada:
c1==>any and c2==>any and c3==>-a -b -c any
c1==>one and c2==>one and c3==>-c -b -f -m mul
c1==>mul and c2==>one and c3==>-c -b -f -m mul
Editar 1:
Percebi que fui estúpido ao usar o script e, na primeira iteração, costumava exit 0
testá-lo apenas na primeira linha, pois tenho muito disso na realidade. Estava funcionando como tem que estar.
Posso obter a saída mencionada mantendo o variable_list
sem modificar o formato/forma de entrada?
(estou usando bash)
Seu problema é com os espaços nos dados. O shell irá dividir a string em palavras em todos os espaços e o
for
loop irá iterar sobre essas palavras.(Para uma solução que não substitui
variable_list
por uma matriz, consulte o final desta resposta.)Em vez disso, use uma matriz adequada:
O uso de um array garante que você possa acessar cada conjunto individual de variáveis como sua própria entrada de array sem depender deles serem delimitados por novas linhas ou algum outro caractere.
O código também está usando "here-strings"
bash
para enviar a string paracut
(em vez deecho
um pipe).Ou, muito mais eficientemente,
A definição
IFS
de dois pontos pararead
fará com queread
a entrada seja dividida em dois pontos (em vez de espaços, tabulações e novas linhas).Observe que toda a citação acima é significativa. Sem as aspas duplas, o shell executaria divisão de palavras e globbing de nome de arquivo nos valores de
variable_list
evar
nas trêsc
variáveis.Relacionado:
Se tudo o que você procura é essa saída específica, você pode trapacear um pouco:
Isso executa o
printf
em um subshell para que a configuraçãoIFS
e a opção do shell-f
(noglob
) não afetem o restante do script. DefinirIFS
dois pontos aqui fará com que o shell expanda a matriz sem aspasvariable_list
em três conjuntos de três argumentos paraprintf
.printf
imprimirá os três primeiros de acordo com sua string de formato e, em seguida, reutilizará esse formato para o próximo conjunto de três argumentos, até que todos os argumentos tenham sido processados.O
set -f
impede que a expansão sem aspas de acione ovariable_list
globbing de nome de arquivo, caso haja algum caractere de globbing de nome de arquivo lá.Usando uma string delimitada por nova linha:
Isso lê os dados da string como se viessem de um arquivo.
Relacionado:
Você pode usar awk para obter sua saída: