如何将 BASH 中这样的字符串转换为 bash 中的数组!
我有一个字符串str,其中包含“title1 title2 title3 title4 title5” (空格分隔的标题)
我希望将 str 修改为一个数组,该数组将每个标题存储在每个索引中。
为了将字符串转换为数组,请说:
$ str="title1 title2 title3 title4 title5"
$ arr=( $str )
除非您引用字符串,否则 shell 将对空格执行分词。
为了遍历由此创建的数组中的元素:
$ for i in "${arr[@]}"; do echo $i; done
title1
title2
title3
title4
title5
另一种使用读取的方法:
read -a array <<< $str
我处于一个不幸的位置,我有一个长期存在的 shell 脚本,该脚本正在从内部使用标量变量升级到使用数组。 但是,用户也可以自己设置这些变量,可选地,使用在启动时获取的文件。
因此,我需要找到一种方法来有条件地将标量转换为数组,具体取决于用户的源脚本是以新方式还是旧方式声明的。
对于上面的简单案例,我的解决方案太过分了,但我想为寻找此解决方案的其他人记录它,因为提出处理我的用例的东西并非易事。
因此,我想出的安全可靠地处理所有选项的唯一方法是:
convert_array() {
__array_name="$1"; shift
__declaration="$(declare -p "$__array_name" 2>/dev/null)"
if [ -z "${__declaration}" ]; then
# variable is not set
eval "${__array_name}=()"
elif [ "$(echo "${__declaration}" | grep -c '^declare \-a')" -eq 0 ]; then
# variable is not an array
__existing_value="$(eval echo "\${$__array_name}" | sed -e 's,^[[:space:]]*,,' -e 's,[[:space:]]*$,,')"
unset "${__array_name?}"
IFS=" " read -r -a "${__array_name?}" <<< "${__existing_value}"
fi
}
它干净地处理所有情况:现有变量、现有数组和根本没有设置。
另请注意,虽然这看起来有点矫枉过正:
__existing_value="$(eval echo "\${$__array_name}" | sed -e 's,^[[:space:]]*,,' -e 's,[[:space:]]*$,,')"
...它处理大多数人正在构建他们的源配置的情况,如下所示:
ADDITIONAL_OPTIONS="${ADDITIONAL_OPTIONS} -Xmx2g"
ADDITIONAL_OPTIONS="${ADDITIONAL_OPTIONS} -Dsome.property=foo"
在这些情况下,$ADDITIONAL_OPTIONS
变量将以空格开头。如果您知道您的输入不需要修剪,那一点是不必要的。
test_foo() {
convert_array FOO
for VAR in "${FOO[@]}"; do
echo "var=$VAR"
done
}
$ FOO="foo bar baz"
$ test_foo
var=foo
var=bar
var=baz
$ unset FOO
$ test_foo
$ FOO=(foo bar baz "something with spaces")
$ test_foo
var=foo
var=bar
var=baz
var=something with spaces