Impression d'un tableau dans un fichier avec chaque élément du tableau dans une nouvelle ligne dans bash

13

J'essaie le contenu d'un tableau dans un fichier avec chaque élément du tableau dans une nouvelle ligne dans le fichier.

IFS=$'\n'   
echo "${mtches[@]}" > sample1.txt 


Le contenu des mtches est "qwe" et "asd". Mais le sample1.txtfichier contient qwe asdsur une seule ligne. Pourquoi ne prend-il pas la valeur IFS dans l'image?

Ashwin
la source

Réponses:

17

Vous devez utiliser à la printfplace deecho :

printf "%s\n" "${mtches[@]}"

Si mtchesest vide, cela produira toujours une ligne vide. Pour en tenir compte:

{ [ "${#mtches[@]}" -eq 0 ] || printf '%s\n' "${mtches[@]}"; } > file

Dans bash(et également les shells POSIX), vous utilisez souvent le tableau de paramètres de position au "$@"lieu de "$*", sauf si vous avez une raison particulière. Cela est également vrai dans les shells qui prennent en charge les tableaux réguliers, à partir de man bash - section Arrays :

Tout élément d'un tableau peut être référencé à l'aide de $ {name [indice]}. Les accolades sont nécessaires pour éviter les conflits avec les opérateurs d'extension de nom de fichier du shell. Si l'indice est «@» ou «*», le mot s'étend à tous les membres du nom du tableau. Ces indices ne diffèrent que lorsque le mot apparaît entre guillemets doubles. Si le mot est entre guillemets, $ {name [*]} se développe en un seul mot avec la valeur de chaque membre du tableau séparé par le premier caractère de la variable IFS, et $ {name [@]} développe chaque élément de nom à un mot distinct. Lorsqu'il n'y a pas de membres du tableau, $ {name [@]} se développe à rien. Si l'expansion entre guillemets se produit dans un mot, l'expansion du premier paramètre est jointe à la partie de début du mot d'origine et l'expansion du dernier paramètre est jointe à la dernière partie du mot d'origine.

Utilisez uniquement "${array[*]}"lorsque vous souhaitez joindre tous les éléments du tableau à une chaîne.

cuonglm
la source
Comment cela fait-il une différence?
Ashwin
7

Vous souhaitez utiliser à la ${mtches[*]}place.

Lorsque vous utilisez "${mtches[@]}", peu importe la valeur de $IFS, bash divisera le tableau en plusieurs arguments. Ce que vous voulez, c'est un seul argument avec chaque élément de tableau joint par \n. ${mtches[*]}accomplit cela.

Également comme moyen de configuration temporaire $IFS, vous pouvez faire:

( IFS=$'\n'; echo "${mtches[*]}" > sample1.txt )

Ensuite, vous n'avez pas à vous soucier de le remettre en place.

Patrick
la source
pubs.opengroup.org/onlinepubs/9699919799/utilities/… <- Référence POSIX (cela ne s'applique pas uniquement à bash).
Mat
Ou utilisez printf...
jasonwryan
2

Utilisation pour :

for each in "${alpha[@]}"
do
  echo "$each"
done

Utiliser l' histoire ; notez que cela échouera si vos valeurs contiennent !:

history -p "${alpha[@]}"

Utilisation du nom de base ; notez que cela échouera si vos valeurs contiennent /:

basename -a "${alpha[@]}"

Utilisation de shuf ; notez que les résultats peuvent ne pas sortir dans l'ordre:

shuf -e "${alpha[@]}"
Steven Penny
la source