我有一个变量,其中包含一个空格分隔字符串:

line="1 1.50 string"

我想用空格作为分隔符分割该字符串,并将结果存储在一个数组中,以便如下:

echo ${arr[0]}
echo ${arr[1]}
echo ${arr[2]}

输出

1
1.50
string

我在某个地方发现了一个行不通的解决方案:

arr=$(echo ${line})

如果我在这之后运行上面的echo语句,我得到:

1 1.50 string
[empty line]
[empty line]

我也试过

IFS=" "
arr=$(echo ${line})

同样的结果。有人能帮帮我吗?


当前回答

如果需要扩展参数,请尝试:

eval "arr=($line)"

例如,以以下代码为例。

line='a b "c d" "*" *'
eval "arr=($line)"
for s in "${arr[@]}"; do 
    echo "$s"
done

如果当前目录包含a.txt、b.txt和c.txt文件,那么执行代码将产生以下输出。

a
b
c d
*
a.txt
b.txt
c.txt

其他回答

为了将字符串转换为数组,从字符串创建一个数组,让字符串根据IFS(内部字段分隔符)变量自然分割,默认情况下是空格字符:

arr=($line)

或者使用herestring(<<<)操作符将字符串传递给read命令的stdin:

read -a arr <<< "$line"

对于第一个例子,重要的是不要在$line周围使用引号,因为这样可以将字符串分割为多个元素。

参见:https://github.com/koalaman/shellcheck/wiki/SC2206

In: arr=($line)。“split”和“glob”联系在一起。 通配符(*,?和[])将扩展到匹配的文件名。

正确的解决方案只是稍微复杂一点:

IFS=' ' read -a arr <<< "$line"

没有全球通问题;分隔字符设置在$IFS中,变量加引号。

如果需要扩展参数,请尝试:

eval "arr=($line)"

例如,以以下代码为例。

line='a b "c d" "*" *'
eval "arr=($line)"
for s in "${arr[@]}"; do 
    echo "$s"
done

如果当前目录包含a.txt、b.txt和c.txt文件,那么执行代码将产生以下输出。

a
b
c d
*
a.txt
b.txt
c.txt

试试这个:

arr=(`echo ${line}`);
line="1 1.50 string"

arr=$( $line | tr " " "\n")

for x in $arr
do
echo "> [$x]"
done