Bash以声明方式定义要循环的列表

时间:2012-05-21 14:35:32

标签: bash loops

在bash中,我经常编写脚本,循环遍历我定义的字符串列表。

e.g。

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

但是我想定义列表(在循环之前保持它干净),以便它包含空格并且没有单独的文件:

e.g。 (但这不起作用)

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读取下面的答案,因为你可以附加到数组..我不知道你可以)。

其他人如何使用单独的文件声明性地在bash中定义列表?

抱歉,我忘了提及我想在for循环逻辑之前在文件顶部定义列表

5 个答案:

答案 0 :(得分:4)

您可以像这样使用“HERE文件”:

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

答案 1 :(得分:3)

阵列并不难使用:

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

如果您有这种需要,这还有一个额外的好处,即允许每个列表项包含空格。

答案 2 :(得分:3)

while read -r line
do
    var+=$line$'\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

答案 3 :(得分:2)

这里有更好的答案,但您也可以在\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

答案 4 :(得分:0)

如果您可以使用while循环而不是for循环,则可以使用while read构造和“此处文档”:

#!/bin/bash

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

参考:How does ` cat << EOF` work in bash?