Simple une ligne astuce pour vider un tableau
J'ai ajouté une valeur avec des espaces :
foo=()
foo[12]="bar"
foo[42]="foo bar baz"
foo[35]="baz"
Moi, je dépose rapidement bash ou tableaux associatifs J'utilise
Cette commande en une ligne :
paste <(printf "%s\n" "${!foo[@]}") <(printf "%s\n" "${foo[@]}")
Rendu :
12 bar
35 baz
42 foo bar baz
Expliqué
-
printf "%s\n" "${!foo[@]}"
imprimera tous les clés séparés par un nouvelle ligne ,
-
printf "%s\n" "${foo[@]}"
imprimera tous les valeurs séparés par un nouvelle ligne ,
-
paste <(cmd1) <(cmd2)
fusionnera la sortie de cmd1
et cmd2
ligne par ligne.
Tunning
Cela pourrait être réglé par -d
interrupteur :
paste -d : <(printf "%s\n" "${!foo[@]}") <(printf "%s\n" "${foo[@]}")
12:bar
35:baz
42:foo bar baz
ou même :
paste -d = <(printf "foo[%s]\n" "${!foo[@]}") <(printf "'%s'\n" "${foo[@]}")
foo[12]='bar'
foo[35]='baz'
foo[42]='foo bar baz'
Un tableau associatif fonctionnera de la même manière :
declare -A bar=([foo]=snoopy [bar]=nice [baz]=cool [foo bar]='Hello world!')
paste -d = <(printf "bar[%s]\n" "${!bar[@]}") <(printf '"%s"\n' "${bar[@]}")
bar[foo bar]="Hello world!"
bar[foo]="snoopy"
bar[bar]="nice"
bar[baz]="cool"
Question avec nouvelles lignes ou des caractères spéciaux
Malheureusement, il existe au moins une condition qui fait que cela ne fonctionne plus : lorsque la variable contient une nouvelle ligne :
foo[17]=$'There is one\nnewline'
Commande paste
va fusionner ligne par ligne, donc la sortie sera fausse :
paste -d = <(printf "foo[%s]\n" "${!foo[@]}") <(printf "'%s'\n" "${foo[@]}")
foo[12]='bar'
foo[17]='There is one
foo[35]=newline'
foo[42]='baz'
='foo bar baz'
Pour ce travail, vous pourriez utiliser %q
au lieu de %s
en second lieu printf
(et la citation) :
paste -d = <(printf "foo[%s]\n" "${!foo[@]}") <(printf "%q\n" "${foo[@]}")
Le rendu sera parfait :
foo[12]=bar
foo[17]=$'There is one\nnewline'
foo[35]=baz
foo[42]=foo\ bar\ baz
De man bash
:
%q causes printf to output the corresponding argument in a
format that can be reused as shell input.