it-swarm.com.de

Wie konvertiere ich eine Bash-Array-Variable in einen mit Zeilenumbrüchen getrennten String?

Ich möchte eine Bash-Array-Variable in eine Datei schreiben, wobei sich jedes Element in einer neuen Zeile befindet. Ich könnte dies mit einer for-Schleife tun, aber gibt es eine andere (sauberere) Möglichkeit, die Elemente mit \n zu verbinden?

48
ACyclic

Hier ist eine Methode, die die Bash-Parameter-Erweiterung und die Sondervariable IFS verwendet.

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

Wir verwenden eine Subshell, um zu vermeiden, dass der Wert von IFS in der aktuellen Umgebung überschrieben wird. In dieser Subshell ändern wir dann den Wert von IFS so, dass das erste Zeichen eine neue Zeile ist (unter Verwendung von $'...' quoting). Schließlich verwenden wir die Parametererweiterung, um den Inhalt des Arrays als einzelnes Wort zu drucken. Jedes Element wird durch das erste Zeichen von IFS getrennt.

So erfassen Sie eine Variable:

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

Wenn Ihre Bash neu genug ist (4.2 oder neuer), können (und sollten) Sie weiterhin printf mit der Option -v verwenden:

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

In beiden Fällen möchten Sie möglicherweise nicht die letzte Zeile in var. Es zu entfernen:

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

Sie können printf verwenden, um jedes Array-Element in einer eigenen Zeile zu drucken:

 $ System=('s1' 's2' 's3' 's4 4 4')
 $ printf "%s\n"  "${System[@]}"
s1
s2
s3
s4 4 4
26
rush
awk -v sep='\n' 'BEGIN{ORS=OFS="";for(i=1;i<ARGC;i++){print ARGV[i],ARGC-i-1?sep:""}}' "${arr[@]}"

oder

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

oder

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

oder

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

oder

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

oder

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

oder

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

oder

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

das ist alles, woran ich mich erinnern kann.

6
Meow

Die oben genannten Lösungen sind so ziemlich alles, aber die ursprüngliche Frage fragt nach der Ausgabe in eine Datei:

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

Anmerkungen: 1) 'echo' liefert den letzten Zeilenumbruch 2) Wenn diese Datei nur noch einmal von der Bash eingelesen wird, kann -p die gewünschte Serialisierung sein.

2
Brian Chrisman

Verwenden von für :

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

Verwenden von history ; Beachten Sie, dass dies fehlschlägt, wenn Ihre Werte ! enthalten:

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

Using basename ; Beachten Sie, dass dies fehlschlägt, wenn Ihre Werte / enthalten:

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

Using shuf ; Beachten Sie, dass die Ergebnisse möglicherweise nicht in der richtigen Reihenfolge angezeigt werden:

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