Bash, декларативно определяющий список для цикла

В bash я часто создаю сценарии, в которых я зацикливаюсь на списке строк, которые я определяю.

например

for a in 1 2 3 4; do echo $a; done

Однако я хотел бы определить список (до цикла, чтобы он был чистым), чтобы он содержал пробелы и не содержал отдельный файл:

например (НО ЭТО НЕ БУДЕТ РАБОТАТЬ)

read -r VAR <<HERE
list item 1
list item 2
list item 3
...
HERE

for a in $VAR; do echo $a; done

Ожидаемый результат выше (хотелось бы):

list item 1
list item 2
list item 3
etc...

Но вы получите:

list
item
1

Я мог бы использовать массивы, но мне пришлось бы индексировать каждый элемент в массиве (EDIT read answers below as you can append to arrays.. I did not know you could).

How do others declaratively define lists in bash with out using separate files?

Sorry I forgot to mention I want to define the list at the top of the file before the for loop logic

Ответы на вопрос(5)

Когда вы можете использоватьwhile цикл вместоfor цикл, вы можете использоватьwhile read построить и «вот документ»:

#!/bin/bash

while read LINE; do
    echo "${LINE}"
done << EOF
list item 1
list item 2
list item 3
EOF

ссылка:Как работает `cat & lt; & lt; Работа в баше?

Здесь есть лучшие ответы, но вы также можете разграничить прочитанное на\n и временно изменить переменную, чтобы разделить на новые строки вместо пробелов вfor цикл с использованиемIFS переменная окружения.

read -d \n -r VAR <<HERE
list item 1
list item 2
list item 3
HERE

IFS_BAK=$IFS
IFS="\n"
for a in $VAR; do echo $a; done
IFS=$IFS_BAK
Решение Вопроса

Массивы не так сложны в использовании:

readarray <<HERE
this is my first line
this is my second line
this is my third line
HERE

# Pre bash-4, you would need to build the array more explicity
# Just like readarray defaults to MAPFILE, so read defaults to REPLY
# Tip o' the hat to Dennis Williamson for pointing out that arrays
# are easily appended to.
# while read ; do
#    MAPFILE+=("$REPLY")
# done

for a in "${MAPFILE[@]}"; do
    echo "$a"
done

Это дает дополнительное преимущество, позволяя каждому элементу списка содержать пробелы, если у вас есть такая необходимость.

while read -r line
do
    var+=$line
while read -r line
do
    var+=$line$'\n'
done <<EOF
foo bar
baz qux
EOF

while read -r line
do
    echo "[$line]"
done <<<"$var"
apos;\n' done <<EOF foo bar baz qux EOF while read -r line do echo "[$line]" done <<<"$var"

Зачем вам нужно индексировать массивы? Вы можете добавлять к массивам и перебирать их, не используя индексы.

array+=(value)
for item in "${array[@]}"
do
    something with "$item"
done

Вы можете использовать & quot; Документ ЗДЕСЬ & quot; как это:

while read a ; do echo "Line: $a" ; done <<HERE
123 ab c
def aldkfgjlaskdjf lkajsdlfkjlasdjf
asl;kdfj ;laksjdf;lkj asd;lf sdpf -aa8
HERE

Ваш ответ на вопрос