65 votes

Comment convertir une variable de tableau bash en une chaîne de caractères délimitée par des nouvelles lignes ?

Je veux écrire une variable de tableau bash dans un fichier, avec chaque élément sur une nouvelle ligne. Je pourrais le faire avec un boucle for, mais existe-t-il un autre moyen (plus propre) de joindre les éléments avec \n ?

85voto

chepner Points 6381

Voici une méthode qui utilise l'expansion des paramètres de bash et sa fonction IFS variable spéciale.

$ System=('s1' 's2' 's3' 's4 4 4')
$ ( IFS=$'\n'; echo "${System[*]}" )

Nous utilisons un subshell pour éviter d'écraser la valeur de IFS dans l'environnement actuel. Dans ce sous-shell, nous modifions ensuite la valeur de IFS de sorte que le premier caractère soit une nouvelle ligne (en utilisant $'...' citant). Enfin, nous utilisons l'expansion des paramètres pour imprimer le contenu du tableau sous la forme d'un seul mot ; chaque élément est séparé par le premier caractère de la commande IFS .

Pour capturer à une variable :

$ var=$( IFS=$'\n'; echo "${System[*]}" )

Si votre bash est assez récent (4.2 ou plus), vous pouvez (et devriez) toujours utiliser printf avec le -v option :

$ printf -v var "%s\n" "${System[@]}"

Dans un cas comme dans l'autre, il se peut que vous ne vouliez pas que le dernier saut de ligne dans var . Pour l'enlever :

$ var=${var%?}    # Remove the final character of var

32voto

Will Points 311

Vous pouvez utiliser printf pour imprimer chaque élément du tableau sur sa propre ligne :

 $ System=('s1' 's2' 's3' 's4 4 4')
 $ printf "%s\n"  "${System[@]}"
s1
s2
s3
s4 4 4

9voto

Meow Points 275
awk -v sep='\n' 'BEGIN{ORS=OFS="";for(i=1;i<ARGC;i++){print ARGV[i],ARGC-i-1?sep:""}}' "${arr[@]}"

o

perl -le 'print join "\n",@ARGV' "${arr[@]}"

o

python -c 'import sys;print "\n".join(sys.argv[1:])' "${arr[@]}"

o

sh -c 'IFS=$'\''\n'\'';echo "$*"' '' "${arr[@]}"

o

lua <(echo 'print(table.concat(arg,"\n"))') "${arr[@]}"

o

tclsh <(echo 'puts [join $argv "\n"]') "${arr[@]}"

o

php -r 'echo implode("\n",array_slice($argv,1));' -- "${arr[@]}"

o

ruby -e 'puts ARGV.join("\n")' "${arr[@]}"

c'est tout ce que je peux rappeler jusqu'à présent.

2voto

Brian Chrisman Points 128

Les solutions ci-dessus sont à peu près complètes, mais la question originale demande une sortie vers un fichier :

$ a=(a b c d e)
$ ( IFS=$'\n'; echo "${a[*]}" ) > /tmp/file
$ cat /tmp/file
a
b
c
d
e
$

Notes : 1) 'echo' fournit le dernier saut de ligne. 2) Si ce fichier sera simplement lu par bash, alors declare -p peut être la sérialisation souhaitée.

2voto

Red Tux Points 2074

Utilisation de pour :

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

Utilisation de histoire ; notez que cela échouera si vos valeurs contiennent ! :

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

Utilisation de 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[@]}"

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X