Друкувати елементи масиву на окремих рядках у Bash?


229

Як надрукувати елемент масиву масиву Bash в окремих рядках? Це працює, але, безумовно, є кращий спосіб:

$ my_array=(one two three)
$ for i in ${my_array[@]}; do echo $i; done
one
two
three

Спробував це, але нічого не вийшло:

$ IFS=$'\n' echo ${my_array[*]}
one two three

Відповіді:


436

Спробуйте зробити це:

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

Різниця між $@та $*:

  • Без котирування, результати не визначені. У Bash обидва розширюються на окремі аргументи, а потім розщеплюють слово та глобус.

  • Цитується, "$@"розширює кожен елемент як окремий аргумент, в той час як "$*" розширюється на аргументи, об'єднані в один аргумент: "$1c$2c..."(де cє перша таблиця IFS).

Ви майже завжди хочете "$@". Те саме стосується "${arr[@]}".

Завжди цитуйте їх!


5
І зауважте, подвійні лапки навколо змінної посилання є важливими, якщо ви хочете переконатися, що елементи з внутрішніми пробілами не випадково розбиті.
danfuzz

4
@sputnick: не працює, елементи масиву закінчуються в одному рядку
Axel Bregnsbo

1
Назвіть два дефіси після команди? Я не знайшов жодних посилань на це в посібнику.
joanpau

3
Чи є спосіб зробити так, щоб він не мав порожніх рядків, якщо в масиві немає елементів без необхідності | grep -v '^$'?
Ноель Яп

2
@espaciomore '% s \ n' - формат для виводу функції printf. % s означає заповнювач для аргументу рядка (у цьому випадку елемент масиву) і \ n додає розрив рядка після цього. Таким чином, буде виведено рядок і перерив рядка у висновку для кожного елемента масиву.
Коджа

71

Просто наведіть аргумент на лунку:

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

допоміжна оболонка допомагає відновити IFS після використання


3
Вибачте за перреальне, я перемістив свій галочку на sputnick, незважаючи на те, що вам більше подобається ваше рішення, просто тому, що я дізнався про функцію 'printf'.
Аксель Брегнсбо

3
Дякую за цю відповідь - мені це подобається! Занадто погані завдання ставляться після розширення, тому IFS=$'\n' echo "${my_array[*]}"не працює. Що ж, добре!
cxw

@cxw, що ви маєте на увазі під "завданнями"?
Стівен Шоу

1
@bschlueter, я спробував з Bash 4 - 4.4.23 (1) -випуск - і це працює!
Стівен Шоу

1
@cxw Ах, я не бачив, що ти намагався там зробити. Я думаю, що це не працює, тому що echoце вбудований в Bash. Однак ви можете загорнути його у функцію, і вона спрацює! gist.github.com/steshaw/53ba0095bce8ccab52d26a14375dedb8
Стівен Шоу

40

Використання для :

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

Використання історії ; зауважте, що це не вдасться, якщо ваші значення містять !:

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

Використання базового імені ; зауважте, що це не вдасться, якщо ваші значення містять /:

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

Використання шуф ; зауважте, що результати можуть вийти не для того, щоб:

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

19
"шуф" ... "може не вийти на порядок" ... веселий.
Уолф

4
для шуф. Хто б міг подумати про це?
fbicknel

3

Я спробував відповіді тут у гігантському для ... якщо цикл, але не отримав ніякої радості - тому я зробив це так, можливо, безладно, але зробив роботу:

 # EXP_LIST2 is iterated    
 # imagine a for loop
     EXP_LIST="List item"    
     EXP_LIST2="$EXP_LIST2 \n $EXP_LIST"
 done 
 echo -e $EXP_LIST2

хоча це додало простір до списку, що добре - я хотів, щоб він був трохи відступ. Також припустимо, що "\ n" може бути надруковано в оригіналі $ EP_LIST.


5
Це не схоже на повний приклад.
kenorb

3

Ще один корисний варіант - це труба для tr:

echo "${my_array[@]}" | tr ' ' '\n'

Це виглядає просто і компактно


11
За винятком цих перерв наmy_array=( "one two" three )
Майк Холт

Виправлено це подвійними лапками.
Стівен Шоу

Не працювало так, як рекламується у версії Bash 4+, довелося використовувати echo "${my_array[@]}" | tr '' ' \n', хоча особисто я б уникав такого використання echo, де trмій вибір, я думаю, щось подібне tr '' ' \n' <<<"${my_array[@]}"може бути трохи простіше прочитати пізніше.
S0AndS0
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.