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

例如,给定一行:

Paris, France, Europe

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

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

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


当前回答

另一种方法是:

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

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

for i in ${arr[@]}; do echo $i; done

其他回答

更新:不要这样做,由于eval的问题。

不那么讲究礼节的:

IFS=', ' eval 'array=($string)'

e.g.

string="foo, bar,baz"
IFS=', ' eval 'array=($string)'
echo ${array[1]} # -> bar
t="one,two,three"
a=($(echo "$t" | tr ',' '\n'))
echo "${a[2]}"

打印三

输入代码here多字符分隔符解决方案。

正如其他人在这篇文章中指出的,OP的问题给出了一个用逗号分隔的字符串被解析成数组的例子,但没有指出他/她是否只对逗号分隔符、单字符分隔符或多字符分隔符感兴趣。

由于谷歌倾向于将这个答案排在搜索结果的顶部或附近,所以我想为读者提供一个关于多个字符分隔符问题的有力答案,因为至少有一个回答也提到了这个问题。

如果您正在寻找多字符分隔符问题的解决方案,我建议您查看Mallikarjun M的帖子,特别是来自gniourf_gniourf的回复 谁提供了这个优雅的纯BASH解决方案使用参数展开:

#!/bin/bash
str="LearnABCtoABCSplitABCaABCString"
delimiter=ABC
s=$str$delimiter
array=();
while [[ $s ]]; do
    array+=( "${s%%"$delimiter"*}" );
    s=${s#*"$delimiter"};
done;
declare -p array

链接到引用的评论/引用的帖子

链接到引用的问题:如何在bash中拆分多字符分隔符上的字符串?


2022年8月3日

Xebeche在下面的评论中提出了一个很好的观点。在审查了他们建议的编辑之后,我修改了gniourf_gniourf提供的脚本,并添加了注释,以便于理解脚本正在做什么。我还将双括号[[]]改为单括号,以提高兼容性,因为许多SHell变体不支持双括号表法。在本例中,对于BaSH,逻辑在单括号或双括号内工作。

#!/bin/bash
  
str="LearnABCtoABCSplitABCABCaABCStringABC"
delimiter="ABC"
array=()

while [ "$str" ]; do

    # parse next sub-string, left of next delimiter
    substring="${str%%"$delimiter"*}" 

    # when substring = delimiter, truncate leading delimiter
    # (i.e. pattern is "$delimiter$delimiter")
    [ -z "$substring" ] && str="${str#"$delimiter"}" && continue

    # create next array element with parsed substring
    array+=( "$substring" )

    # remaining string to the right of delimiter becomes next string to be evaluated
    str="${str:${#substring}}"

    # prevent infinite loop when last substring = delimiter
    [ "$str" == "$delimiter" ] && break

done

declare -p array

不加评论:

#!/bin/bash
str="LearnABCtoABCSplitABCABCaABCStringABC"
delimiter="ABC"
array=()
while [ "$str" ]; do
    substring="${str%%"$delimiter"*}" 
    [ -z "$substring" ] && str="${str#"$delimiter"}" && continue
    array+=( "$substring" )
    str="${str:${#substring}}"
    [ "$str" == "$delimiter" ] && break
done
declare -p array

这适用于给定的数据:

$ aaa='Paris, France, Europe'
$ mapfile -td ',' aaaa < <(echo -n "${aaa//, /,}")
$ declare -p aaaa

结果:

declare -a aaaa=([0]="Paris" [1]="France" [2]="Europe")

它也适用于带空格的扩展数据,例如“New York”:

$ aaa="New York, Paris, New Jersey, Hampshire"
$ mapfile -td ',' aaaa < <(echo -n "${aaa//, /,}")
$ declare -p aaaa

结果:

declare -a aaaa=([0]="New York" [1]="Paris" [2]="New Jersey" [3]="Hampshire")

如果你使用macOS,不能使用readarray,你可以简单地这样做-

MY_STRING="string1 string2 string3"
array=($MY_STRING)

要遍历元素:

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