在Bash中将分隔的字符串读入数组

Nik*_*vak 197 arrays string bash shell

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

line="1 1.50 string"
Run Code Online (Sandbox Code Playgroud)

我想将带有空格的字符串拆分为分隔符并将结果存储在数组中,以便以下内容:

echo ${arr[0]}
echo ${arr[1]}
echo ${arr[2]}
Run Code Online (Sandbox Code Playgroud)

输出

1
1.50
string
Run Code Online (Sandbox Code Playgroud)

在某个地方我找到了一个不起作用的解决方案:

arr=$(echo ${line})
Run Code Online (Sandbox Code Playgroud)

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

1 1.50 string
[empty line]
[empty line]
Run Code Online (Sandbox Code Playgroud)

我也试过了

IFS=" "
arr=$(echo ${line})
Run Code Online (Sandbox Code Playgroud)

结果相同.有人可以帮帮忙吗?

kev*_*kev 312

要将字符串转换为数组,请使用

arr=($line)
Run Code Online (Sandbox Code Playgroud)

要么

read -a arr <<< $line
Run Code Online (Sandbox Code Playgroud)

至关重要的是不要使用引号,因为这样可以解决问题.

  • +1.在这种情况下,最重要的是保持变量不带引号. (41认同)
  • 如果`$ line`中包含全局字符,则两种方式都可能失败.`mkdir x && cd x && touch ABC && line ="*"arr =($ line); echo $ {#arr [@]}`给出3 (13认同)
  • 值得注意的是,这不适用于ZSH (9认同)
  • 并对你美丽的新阵列进行健全检查:`for $ in $ {arr [@]}; 回声$ i; done` (7认同)
  • 或者只是`echo $ {arr [@]}` (5认同)
  • @Tino No.当`line ='*'`时,`read -a arr <<< $ line`总是有效,但只有`arr =($ line)`失败. (3认同)
  • `declare -a"arr =($ line)"`将忽略引用字符串中的`IFS`分隔符 (2认同)
  • 两种解决方案都适用于cmd-line.`arr =($ line)`在bash脚本中对我不起作用,而`read -a arr <<< $ line`确实如此. (2认同)

小智 37

试试这个:

arr=(`echo ${line}`);
Run Code Online (Sandbox Code Playgroud)

  • 很好 - 这个解决方案也适用于Z shell,其中一些其他方法失败. (5认同)
  • 备注:当行中有 '*' 时,这也不起作用,例如 `line='*'` (2认同)

sor*_*tar 28

在:arr=( $line )."分裂"与"glob"相关联.
通配符(*,?[])将扩展为匹配的文件名.

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

IFS=' ' read -a arr <<< "$line"
Run Code Online (Sandbox Code Playgroud)

没有全球化的问题; 设置分割字符$IFS,引用变量.

  • 这应该是公认的答案.[已接受答案](/sf/answers/650581081/)中的语句`arr =($ line)`会遇到全局问题.例如,尝试:`line ="twinkling*"; ARR =($线); declare -p arr`. (4认同)
  • 我得到 `func:read:5: bad option: -a` (2认同)

Dav*_*son 5

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

eval "arr=($line)"
Run Code Online (Sandbox Code Playgroud)

例如,采用以下代码。

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

如果当前目录包含的文件a.txtb.txt并且c.txt,然后执行该代码会产生以下输出。

a
b
c d
*
a.txt
b.txt
c.txt
Run Code Online (Sandbox Code Playgroud)