Drukowanie tablicy do pliku z każdym elementem tablicy w nowej linii w bash

13

Próbuję zawartość tablicy do pliku z każdym elementem tablicy w nowej linii w pliku.

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


Zawartość matchów to „qwe” i „asd”. Ale sample1.txtplik zawiera qwe asdw jednym wierszu. Dlaczego nie bierze wartości IFS na zdjęciu?

Ashwin
źródło

Odpowiedzi:

17

Państwo powinno używać printfzamiastecho :

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

Jeśli mtchesjest pusty, to nadal wyświetla jeden pusty wiersz. Aby to uwzględnić:

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

W bash(a także powłoki POSIX), często można wykorzystywać parametry pozycyjne tablicę jako "$@"zamiast "$*", chyba że masz szczególny powód. Dotyczy to również powłok, które obsługują zwykłe tablice, od man bash - sekcja Tablice :

Do dowolnego elementu tablicy można odwoływać się za pomocą $ {name [subscript]}. Nawiasy klamrowe są wymagane, aby uniknąć konfliktów z operatorami rozszerzenia nazw plików powłoki. Jeśli indeks dolny to „@” lub „*”, to słowo rozszerza się na wszystkich członków nazwy tablicy. Te indeksy dolne różnią się tylko wtedy, gdy słowo pojawia się w cudzysłowie. Jeśli słowo jest cytowane podwójnie, $ {nazwa [*]} rozwija się do pojedynczego słowa z wartością każdego elementu tablicy oddzieloną pierwszym znakiem zmiennej IFS, a $ {nazwa [@]} rozwija każdy element nazwy na osobne słowo. Gdy nie ma członków tablicy, $ {name [@]} rozwija się do zera. Jeśli rozwinięcie podwójnego cudzysłowu występuje w jednym słowie, rozwinięcie pierwszego parametru jest połączone z początkową częścią oryginalnego słowa, a rozwinięcie ostatniego parametru jest połączone z ostatnią częścią oryginalnego słowa.

Używaj tylko "${array[*]}"wtedy, gdy chcesz połączyć wszystkie elementy tablicy w łańcuch.

Cuonglm
źródło
Jak to robi różnicę?
Ashwin,
7

Zamiast tego chcesz użyć ${mtches[*]}.

Kiedy używasz "${mtches[@]}", nie ma znaczenia, jaką jest wartość $IFS, bash podzieli tablicę na wiele argumentów. To, czego chcesz, to pojedynczy argument z każdym elementem tablicy dołączonym \n. ${mtches[*]}osiąga to.

Jako tymczasowy sposób ustawienia $IFSmożesz wykonać:

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

Więc nie musisz się przejmować przywracaniem ustawień.

Patrick
źródło
pubs.opengroup.org/onlinepubs/9699919799/utilities/… <- Odniesienie do POSIX (nie dotyczy to tylko bash).
Mat.
Lub użyj printf...
jasonwryan
2

Używanie do :

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

Korzystanie z historii ; zauważ, że to się nie powiedzie, jeśli twoje wartości zawierają !:

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

Korzystanie z basename ; zauważ, że to się nie powiedzie, jeśli twoje wartości zawierają /:

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

Korzystanie z shuf ; pamiętaj, że wyniki mogą nie zostać wyświetlone w kolejności:

shuf -e "${alpha[@]}"
Steven Penny
źródło
1
for ENTRY in ${ARRAY[@]}; do
    echo $ENTRY
done > outfile

Ładne i czytelne i nie oznacza bałaganu w IFS. Oznacza to również, że możesz dostosować obsługę każdej linii.

Steveayre
źródło
1
Ale źle, ponieważ używasz tego, echoczego nie można użyć do dowolnych treści i zapomniałeś podać swoje zmienne . Nieco lepsza wersja została już opublikowana przez StevenPenny
Stéphane Chazelas