Распечатать элементы массива на отдельных строках в 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: не работает, элементы массива заканчиваются одной строкой
Аксель Брегнсбо,

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 ; обратите внимание, что результаты могут не соответствовать порядку:

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
Не похоже на полный пример.
Кенорб

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.