Wie konvertiere ich eine Bash-Array-Variable in einen mit Zeilenumbrüchen getrennten String?
50
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 zu verbinden \n?
Wir verwenden eine Subshell, um zu vermeiden, dass der Wert von IFSin der aktuellen Umgebung überschrieben wird . In dieser Subshell ändern wir dann den Wert von IFSso, dass das erste Zeichen eine neue Zeile ist (unter Verwendung von Anführungszeichen $'...'). Schließlich verwenden wir die Parametererweiterung, um den Inhalt des Arrays als einzelnes Wort auszudrucken. Jedes Element wird durch das erste Zeichen von getrennt IFS.
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 immer noch printfmit der -vOption:
$ printf -v var "%s\n""${System[@]}"
In beiden Fällen möchten Sie möglicherweise nicht die letzte Zeile in var. Es zu entfernen:
Die obigen Lösungen sind ziemlich genau das Richtige, aber in der ursprünglichen Frage wird nach der Ausgabe in eine Datei gefragt:
$ 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.
printf Dies scheint der effizienteste Ansatz zu sein, um einen durch Trennzeichen getrennten String aus einem Array zu erstellen:
# create a delimited string; note that printf doesn't put the trailing delimiter# need to save and restore IFS# it is prudent to put the whole logic on a single line so as to minimize the risk of future code changes breaking the sequence of saving/restoring of IFS
oldIFS=$IFS; IFS=$'\n'; printf -v var "${arr[*]}"; IFS=$oldIFS
# print string to file; note that the newline is required in the format string because printf wouldn't put a trailing delimiter (which is a good thing)
printf '%s\n'"$var"> file
Eine noch einfachere Möglichkeit ist:
delim=$'\n'
printf -v var "%s$delim""${arr[@]}"# create a delimited string
var="${var%$delim}"# remove the trailing delimiter
Beispiel
delim=:
arr=(one two three)
printf -v var "%s$delim""${arr[@]}"# yields one:two:three:
var="${var%$delim}"# yields one:two_three
var=${var%?}
stattdessen sein? Dies ist kein regulärer Ausdruck und entspricht daher.
nur einem Punkt.$ IFS=', ' $ echo ${VAR[*]} first second third $ echo "${VAR[*]}" first,second,third
Sie können
printf
jedes Array-Element in einer eigenen Zeile drucken:quelle
oder
oder
oder
oder
oder
oder
oder
Das ist alles, woran ich mich erinnern kann.
quelle
Die obigen Lösungen sind ziemlich genau das Richtige, aber in der ursprünglichen Frage wird nach der Ausgabe in eine Datei gefragt:
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.
quelle
Verwendung für :
Geschichte benutzen ; Beachten Sie, dass dies fehlschlägt, wenn Ihre Werte Folgendes enthalten
!
:Verwenden des Basisnamens ; Beachten Sie, dass dies fehlschlägt, wenn Ihre Werte Folgendes enthalten
/
:Mit shuf ; Beachten Sie, dass die Ergebnisse möglicherweise nicht in der richtigen Reihenfolge angezeigt werden:
quelle
Meine Einstellung, die nur Bash-Builtins verwendet, ohne zu mutieren
IFS
:Beispiel
Sie können auch ein beliebiges Trennzeichen verwenden:
quelle
printf
Dies scheint der effizienteste Ansatz zu sein, um einen durch Trennzeichen getrennten String aus einem Array zu erstellen:Eine noch einfachere Möglichkeit ist:
Beispiel
quelle