Wie konvertiere ich eine Bash-Array-Variable in einen durch Zeilenumbrüche getrennten String?

Wie konvertiere ich eine Bash-Array-Variable in einen durch Zeilenumbrüche getrennten String?

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

Antwort1

Hier ist eine Möglichkeit, die die Bash-Parametererweiterung und ihre IFSspezielle Variable nutzt.

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

Wir verwenden eine Subshell, um das Überschreiben des Werts von IFSin der aktuellen Umgebung zu vermeiden. In dieser Subshell ändern wir dann den Wert von IFSso, dass das erste Zeichen ein Zeilenumbruch ist (mit $'...'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 höher), können (und sollten) Sie weiterhin printfdie folgende -vOption verwenden:

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

In beiden Fällen möchten Sie möglicherweise nicht, dass am Ende eine neue Zeile steht var. So entfernen Sie sie:

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

Antwort2

Sie können printfjedes Array-Element in einer eigenen Zeile drucken:

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

Antwort3

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 bislang erinnern kann.

Antwort4

Verwenden vonfür:

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

Verwenden vonGeschichte; beachten Sie, dass dies fehlschlägt, wenn Ihre Werte Folgendes enthalten !:

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

Verwenden vonBasisname; beachten Sie, dass dies fehlschlägt, wenn Ihre Werte Folgendes enthalten /:

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

Verwenden vonschuf; beachten Sie, dass die Ergebnisse möglicherweise nicht in der richtigen Reihenfolge angezeigt werden:

shuf -e "${alpha[@]}"

verwandte Informationen