Linux shell是否支持列表数据结构?

83

这个问题与Does the shell support sets?不同。

我知道很多脚本语言支持列表结构,比如Python、Perl、Ruby和JavaScript,那么Linux Shell呢?

Shell是否支持这样的语法?

for i in list:
do
     print i
done

我首先需要初始化一个列表,例如:

ListName = [ item1, item2, ..., itemn ]

然后对它进行迭代

在编写 shell 脚本时,这是否可行?


1
请注意,Bourne shell / POSIX shell 不支持数组。但是 for item in list of items; do 结构在所有 shell 中都得到了支持。此外,方便地使用通配符循环遍历一组文件;for file in a*.dat 通过扩展通配符构建一个令牌列表(尽管不幸的是,许多用户通过执行类似于 for file in $(ls a*.dat) 的操作来破坏它)。 - tripleee
2个回答

143
它支持列表,但不作为单独的数据结构(暂不考虑数组)。for循环遍历以空格分隔的值的列表(在通用意义上),无论如何创建该列表,包括直接创建的列表:
for i in 1 2 3; do
    echo "$i"
done

或者使用参数扩展:

listVar="1 2 3"
for i in $listVar; do
    echo "$i"
done

或命令替换:

for i in $(echo 1; echo 2; echo 3); do
    echo "$i"
done

数组只是一个特殊的参数,可以包含更有结构的值列表,其中每个元素本身可以包含空格。比较一下区别:

array=("item 1" "item 2" "item 3")
for i in "${array[@]}"; do   # The quotes are necessary here
    echo "$i"
done

list='"item 1" "item 2" "item 3"'
for i in $list; do
    echo $i
done
for i in "$list"; do
    echo $i
done
for i in ${array[@]}; do
    echo $i
done

@符号代表什么意思? - Vini.g.fer
3
这是一个特殊的索引,会导致扩展生成数组的所有元素,而不仅仅是一个特定的元素。 - chepner
我不明白为什么 for i in "${array[@]}"; 会打印出3行。因为 echo ${array[@]} 只会打印一行 item 1 item 2 item 3,所以我期望 for i in "${array[@]}"; 被转换成 for i in "item 1 item 2 item 3";;这样就会得到一行 item 1 item 2 item 3。我错过了什么吗?谢谢。 - Svech87
1
"${array[*]}" 会扩展为 "item 1 item 2 item 3"。"${array[@]}" 扩展为 "item 1" "item 2" "item 3";它将每个元素视为单独的带引号的单词,而不是包含所有元素的单个带引号的单词。 - chepner
数组仅在Bash shell中有效。有没有办法在KSH中实现相同的效果? - Mohammad Azim
你为什么认为 ksh 不支持数组?实际上它是支持的,只是语法在某些地方有些不同。这个回答及其评论并不适合解释这些差异。 - chepner

19

要制作列表,只需这样做

colors=(red orange white "light gray")

从技术上讲,它是一个数组,但是它具有列表的所有功能。
即使Python列表也是使用数组实现的


5
要遍历数组,使用 for item in ${colors[*]}; do echo $item; done - neevek
13
@Neevek,它无法实现你想要的效果;"light gray" 将被视为两个条目 "light" 和 "gray"。你需要使用 "${colors[@]}"(使用@而非*,并放在引号中)。 - chepner
为什么在使用 * 时,“浅灰色”会被视为两个项目?我在哪里可以找到这些详细信息的文档?man sh? - hugemeow
2
基本上这是一个历史性的缺陷,在 Bourne shell 中,$* 在所有情况下都不能正确工作,因此不得不发明 "$@" - tripleee

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接