在Bash脚本中,我希望将一行分割成多个片段,并将它们存储在一个数组中。

例如,给定一行:

Paris, France, Europe

我想让结果数组看起来像这样:

array[0] = Paris
array[1] = France
array[2] = Europe

最好是一个简单的实现;速度并不重要。我该怎么做呢?


当前回答

有时,我发现在已接受的答案中描述的方法不起作用,特别是当分隔符是回车符时。 在这些情况下,我是这样解决的:

string='first line
second line
third line'

oldIFS="$IFS"
IFS='
'
IFS=${IFS:0:1} # this is useful to format your code with tabs
lines=( $string )
IFS="$oldIFS"

for line in "${lines[@]}"
    do
        echo "--> $line"
done

其他回答

试试这个

IFS=', '; array=(Paris, France, Europe)
for item in ${array[@]}; do echo $item; done

这很简单。如果你想,你也可以添加一个声明(并删除逗号):

IFS=' ';declare -a array=(Paris France Europe)

添加IFS是为了撤销上述操作,但在新的bash实例中,它可以在没有IFS的情况下工作

接受的答案适用于一行中的值。如果变量有几行:

string='first line
        second line
        third line'

我们需要一个非常不同的命令来获取所有的行:

While read -r line;做线+ =(“美元线”);完成了< < <字符串" $ "

或者更简单的bash readarray:

readarray -t lines <<<"$string"

利用printf特性很容易打印所有行:

printf ">[%s]\n" "${lines[@]}"

>[first line]
>[        second line]
>[        third line]

另一种方法是:

string="Paris, France, Europe"
IFS=', ' arr=(${string})

现在你的元素被存储在“arr”数组中。 要遍历元素:

for i in ${arr[@]}; do echo $i; done
IFS=', ' read -r -a array <<< "$string"

请注意,$IFS中的字符被单独视为分隔符,因此在这种情况下,字段可以用逗号或空格分隔,而不是两个字符的序列。但有趣的是,当输入中出现逗号时,不会创建空字段,因为空格是经过特殊处理的。

要访问单个元素:

echo "${array[0]}"

要遍历元素:

for element in "${array[@]}"
do
    echo "$element"
done

要同时获取索引和值:

for index in "${!array[@]}"
do
    echo "$index ${array[index]}"
done

最后一个示例很有用,因为Bash数组很稀疏。换句话说,您可以删除一个元素或添加一个元素,然后索引不是连续的。

unset "array[1]"
array[42]=Earth

获取数组中元素的个数:

echo "${#array[@]}"

如上所述,数组可以是稀疏的,所以不应该使用长度来获取最后一个元素。以下是在Bash 4.2及以后版本中可以做到的:

echo "${array[-1]}"

在任何版本的Bash中(从2.05b之后的某个地方):

echo "${array[@]: -1:1}"

较大的负偏移量选择距离数组末端更远的位置。注意旧形式中负号前面的空格。这是必须的。

有时,我发现在已接受的答案中描述的方法不起作用,特别是当分隔符是回车符时。 在这些情况下,我是这样解决的:

string='first line
second line
third line'

oldIFS="$IFS"
IFS='
'
IFS=${IFS:0:1} # this is useful to format your code with tabs
lines=( $string )
IFS="$oldIFS"

for line in "${lines[@]}"
    do
        echo "--> $line"
done