将字符串分配给数组而不是在 bash 脚本中使用读取?

bwo*_*arn 4 arrays bash parsing

在 bash 脚本中,我想将包含由“:”分隔的变量的字符串转换为数组。

我看到建议的方法通常是

IFS=: read -r -a myarray <<< "$mystring"
Run Code Online (Sandbox Code Playgroud)

我改用了一个对我来说看起来更简单的命令:

IFS=: myarray=($mystring)
Run Code Online (Sandbox Code Playgroud)

此外,在我的 PC 上它可以工作。请参阅下面的脚本

#!/bin/bash

mystring="var01:var02:var03:var04"

IFS=: myarray=($mystring)

echo "first variable is" "${myarray[0]}"
echo "second variable is" "${myarray[1]}"
echo "..."
Run Code Online (Sandbox Code Playgroud)

输出是

first variable is var01
second variable is var02
...
Run Code Online (Sandbox Code Playgroud)

但是,由于我没有在网上找到这样的例子,我不确定它是否正确......

在 bash 脚本中使用它会有什么问题?是否符合标准?

谢谢你的建议。

Qua*_*odo 6

很好的第一个问题。您提出的替代方案确实存在问题。首先考虑

$ str='a:%:*'
$ IFS=: read -r -a arr <<< "$str"
$ echo "${arr[@]}"
a % *
Run Code Online (Sandbox Code Playgroud)

结果是预期的。因为"$str"是在此处字符串中引用的,所以它不会进行文件名扩展(称为通配)并且一切都非常正确。

另一方面...

$ str='a:%:*'
$ IFS=: arr=($str)
$ echo "${arr[@]}"
a % 07-13:37:38.png 07-13:37:49.png Documents Downloads Pictures Music Xresources
Run Code Online (Sandbox Code Playgroud)

在第二种情况下,$str不加引号并进行文件名扩展,这意味着*扩展到我当前目录中的所有文件!唉!

这些形式都不是 POSIX 兼容的,因为 POSIX 不在 shell 中定义数组。但是两者在 Bash 中都是完全有效的,尽管正如所展示的,它们做不同的事情。

Bash 手册中的参考:Filename Expansion


正如您所指出的,您可以使用set -f禁用文件名扩展。这将解决 的问题IFS=: arr=($str),但可能会让一些人感到惊讶。如果采用这种方式,请set +f在该行之后立即将其设置回原处,否则该设置将应用于整个脚本的其余部分。它增加了解决方案的复杂性,因此我建议尽可能避免这种情况。