while IFS=, read xx yy zz;do
echo $xx $yy $zz
done < input_file
Isso deve funcionar se o número de campos for constante.
Em vez de echo
use seu comando.
Eu tenho um arquivo de texto dividido da seguinte forma:
field1,field2,field3
xield1,xield2,xield3
dield1,dield2,dield3
gield1,gield2,gield3
Cada uma dessas colunas será um parâmetro para um programa, e eu gostaria que o programa fosse chamado para cada linha
Eu estava esperando por um loop, algo como:
for $i in file
command $field2 -x $field3 -PN -$field1 >> output
done
Qual seria a melhor maneira de realizar algo assim em bash?
while IFS=, read xx yy zz;do
echo $xx $yy $zz
done < input_file
Isso deve funcionar se o número de campos for constante.
Em vez de echo
use seu comando.
Você deve usar um while
com o read
integrado:
while IFS= read -r line;do
fields=($(printf "%s" "$line"|cut -d',' --output-delimiter=' ' -f1-))
command "${fields[1]}" -x "${fields[2]}" ... # ${fields[1]} is field 2
done < your_file_here
Como isso funciona
cut
pega a linha e a divide no delimitador especificado por -d
. --output-delimiter
é o caractere separador que cut
usará para exibir os campos selecionados, aqui escolhemos um espaço para podermos colocar os diferentes campos na matriz fields
. -f1-
. fields
, você pode acessar qualquer campo específico desejado com a sintaxe ${field[number]}
, em que number
é um a menos que o número real do campo desejado, pois a indexação da matriz é baseado em zero no Bash. Nota
Para um número constante de campos
Você pode fazer algo semelhante a resposta do 1_CR :
while IFS= read -r line;do
IFS=, read -r field1 field2 field3 <<-EOI
$line
EOI
command "$field2" -x "$field3" ...
done < your_file_here
O acima, embora pareça mais barulhento, deve funcionar em qualquer shell compatível com POSIX, não apenas Bash.
Você pode obter read
para dividir cada linha em uma matriz em ,
definindo IFS
apropriadamente.
while IFS=, read -r -a input; do
printf "%s\n" "${input[0]}" "${input[1]}"
done < input.txt
Assim, no exemplo acima, você pode acessar cada elemento da matriz usando seu índice, começando com 0.
Esse awk
one-liner fará o que você quiser:
awk -F, '{cmd="echo " $2 " -x " $3 " -PN " $1 ">> output"; system(cmd)}' f.txt
Substitua echo
pelo seu comando e f.txt
pelo arquivo pelo qual você deseja iterar.
Breve explicação: -F,
irá definir ,
como delimitador. cmd
constrói o comando e system(cmd)
chama o comando.
gnu sed pode ser usado também.
sed infile -e 's!^\([^,]*\),\([^,]*\),\([^,]*\)$!command -x -PN !e' >> output
observe o uso da opção e no comando s
Tags bash text-processing csv scripting