Analyse d'un file text délimité dans bash en tant qu'arguments de command

J'ai un file text séparé comme ceci:

field1,field2,field3 xield1,xield2,xield3 dield1,dield2,dield3 gield1,gield2,gield3 

Chacune de ces colonnes sera un paramètre d'un programme, et j'aimerais que le programme soit appelé pour chaque ligne

J'espérais une boucle, quelque chose comme:

 for $i in file command $field2 -x $field3 -PN -$field1 >> output done 

Quelle serait la meilleure façon d'accomplir quelque chose comme ça dans bash?

 while IFS=, read xx yy zz;do echo $xx $yy $zz done < input_file 

Cela devrait fonctionner si le nombre de champs est constant. Au lieu d' echo utilisez votre command.

Vous devriez utiliser un while avec la read embeddede:

 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 

Comment cela fonctionne

  • L'instruction cut prend la ligne et la divise sur le délimiteur spécifié par -d .
  • Le séparateur --output-delimiter est le séparateur que cut utilisera pour afficher les champs sélectionnés, ici nous choisissons un espace pour que nous puissions placer les différents champs dans les fields du tableau.
  • Enfin, nous voulons tous les champs (du champ 1 à la fin) et c'est là que -f1- entre en jeu.
  • Maintenant vous avez les différents champs stockés dans les fields variables du tableau, vous pouvez accéder à n'importe quel champ particulier avec la syntaxe ${field[number]}number est un de less que le numéro de champ réel que vous voulez à Bash.

Remarque

  • Cela échouera si l'un de vos champs contient des espaces.

Pour un nombre constant de champs

Vous pouvez plutôt faire quelque chose de similaire à la réponse de 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 

Ce qui précède, tout en semblant plus bruyant, devrait fonctionner dans n'importe quel shell compatible POSIX, pas seulement Bash.

Vous pouvez read pour séparer chaque ligne dans un tableau , en définissant IFS manière appropriée.

 while IFS=, read -r -a input; do printf "%s\n" "${input[0]}" "${input[1]}" done < input.txt 

Ainsi, dans l'exemple ci-dessus, vous pouvez accéder à chaque élément du tableau en utilisant son index, en commençant par 0.

Ce one-liner awk fera ce que vous voulez:

 awk -F, '{cmd="echo " $2 " -x " $3 " -PN " $1 ">> output"; system(cmd)}' f.txt 

Remplacez echo par votre command et f.txt par le file que vous souhaitez parcourir.

Brève explication: -F, définira , comme délimiteur. cmd construit la command et le system(cmd) appelle la command.

gnu sed peut également être utilisé.

 sed infile -e 's!^\([^,]*\),\([^,]*\),\([^,]*\)$!command \1 -x \2 -PN \3!e' >> output 

notez l'utilisation de l'option e dans la command s