在 bash 中将文本字符串转换为数组

26

如何在BASH中将像这样的字符串转换为bash数组!

我有一个包含"title1 title2 title3 title4 title5"(以空格分隔的标题)的字符串str

我想将str修改为一个数组,该数组将每个标题存储在每个索引中。


2
如果您的标题没有空格,您可以使用:array=($string)$string不需要引号)。如果您的标题包含空格...嗯...这取决于它们是如何形成的。 - gniourf_gniourf
3个回答

42

为了将字符串转换为数组,请执行以下操作:

$ str="title1 title2 title3 title4 title5"
$ arr=( $str )

如果不对字符串进行引号包裹,shell会在空格上执行单词分割。

为了遍历这样创建的数组中的元素:

$ for i in "${arr[@]}"; do echo $i; done
title1
title2
title3
title4
title5

5
注意:这种方法在Zsh中不起作用;请参考http://zsh.sourceforge.net/FAQ/zshfaq03.html。 - anishpatel
要在zsh中实现@anishpatel所说的需求,需要执行以下步骤:
setopt shwordsplit; 执行你想要完成的命令; unsetopt shwordsplit
- Thom Schumacher

5

使用read的另一种方法:

read -a array <<< $str

<<< 是什么作用? - baggiponte
1
重定向变量:https://dev59.com/MG445IYBdhLWcg3wnrki#4775845 - perreal
readarray和read -a有什么区别? - MaXi32

0

我处于一个不幸的境地,因为我有一个长期存在的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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接