Drucken eines Arrays in eine Datei mit jedem Element des Arrays in einer neuen Zeile in Bash

13

Ich versuche den Inhalt eines Arrays in eine Datei mit jedem Element des Arrays in einer neuen Zeile in der Datei.

IFS=$'\n'   
echo "${mtches[@]}" > sample1.txt 


Der Inhalt von mtches ist "qwe" und "asd". Aber die sample1.txtDatei enthält qwe asdin einer einzigen Zeile. Warum wird der IFS-Wert nicht in das Bild aufgenommen?

Ashwin
quelle

Antworten:

16

Sie sollten printfanstelle vonecho :

printf "%s\n" "${mtches[@]}"

Wenn mtchesleer ist, wird immer noch eine leere Zeile ausgegeben. Um das zu erklären:

{ [ "${#mtches[@]}" -eq 0 ] || printf '%s\n' "${mtches[@]}"; } > file

In bash(und POSIX - Shells auch), verwenden Sie häufig Positionsparameter Array als "$@"statt "$*", es sei denn , Sie einen besonderen Grund haben. Dies gilt auch für Shells, die reguläre Arrays unterstützen, von man bash - section Arrays :

Auf jedes Element eines Arrays kann mit $ {name [subscript]} verwiesen werden. Die geschweiften Klammern sind erforderlich, um Konflikte mit den Dateinamenerweiterungsoperatoren der Shell zu vermeiden. Wenn der Index '@' oder '*' ist, wird das Wort auf alle Mitglieder des Arraynamens erweitert. Diese Indizes unterscheiden sich nur, wenn das Wort in doppelten Anführungszeichen steht. Wenn das Wort in doppelte Anführungszeichen eingeschlossen ist, wird $ {name [*]} zu einem einzelnen Wort erweitert, wobei der Wert jedes Arraymitglieds durch das erste Zeichen der IFS-Variablen getrennt wird, und $ {name [@]} erweitert jedes Element des Namens zu einem separaten Wort. Wenn es keine Array-Mitglieder gibt, wird $ {name [@]} zu nichts erweitert. Wenn die Erweiterung in doppelten Anführungszeichen innerhalb eines Wortes auftritt, wird die Erweiterung des ersten Parameters mit dem Anfangsteil des ursprünglichen Wortes verbunden, und die Erweiterung des letzten Parameters wird mit dem letzten Teil des ursprünglichen Wortes verbunden.

Verwenden "${array[*]}"Sie diese Option nur, wenn Sie alle Array-Elemente zu einer Zeichenfolge zusammenfügen möchten.

cuonglm
quelle
Wie macht das einen Unterschied?
Ashwin
7

Sie möchten ${mtches[*]}stattdessen verwenden.

Bei der Verwendung "${mtches[@]}"spielt es keine Rolle, wie hoch der Wert $IFSist. Bash teilt das Array in mehrere Argumente auf. Was Sie wollen, ist ein einzelnes Argument, bei dem jedes Array-Element durch verknüpft ist \n. ${mtches[*]}erreicht dies.

$IFSSie können auch vorübergehend Folgendes tun:

( IFS=$'\n'; echo "${mtches[*]}" > sample1.txt )

Dann müssen Sie sich nicht darum kümmern, es zurückzusetzen.

Patrick
quelle
pubs.opengroup.org/onlinepubs/9699919799/utilities/… <- POSIX-Referenz (dies gilt nicht nur für Bash).
Mat
Oder verwenden Sie printf...
Jasonwryan
2

Verwendung für :

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

Geschichte benutzen ; Beachten Sie, dass dies fehlschlägt, wenn Ihre Werte Folgendes enthalten !:

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

Verwenden des Basisnamens ; Beachten Sie, dass dies fehlschlägt, wenn Ihre Werte Folgendes enthalten /:

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

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

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