3

在 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

我可以使用数组,但我必须索引数组中的每个元素(编辑阅读下面的答案,因为您可以附加到数组..我不知道你可以)。

其他人如何在不使用单独文件的情况下以声明方式在 bash 中定义列表?

对不起,我忘了提到我想在 for 循环逻辑之前定义文件顶部的列表

4

5 回答 5

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
于 2012-05-21T14:42:57.600 回答
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

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

于 2012-05-21T14:46:50.040 回答
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
于 2012-05-21T14:50:29.183 回答
2

这里有更好的答案,但您也可以使用环境变量在循环中分隔读取\n并临时更改变量以在换行符上拆分而不是空格。forIFS

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
于 2012-05-21T14:58:21.877 回答
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

ref: `cat << EOF` 在 bash 中是如何工作的?

于 2012-05-21T14:46:21.603 回答