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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19657683/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-07 01:12:27  来源:igfitidea点击:

Convert a text string in bash to array

linuxbashshellunixksh

提问by Ayush Mishra

How do i convert a string like this in BASH to an array in bash!

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

I have a string strwhich contains "title1 title2 title3 title4 title5"(space seperated titles)

我有一个字符串str,其中包含“title1 title2 title3 title4 title5”(空格分隔的标题)

I want the str to modified to an array which will store each title in each index.

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

采纳答案by devnull

In order to convert the string to an array, say:

为了将字符串转换为数组,请说:

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

The shell would perform word splitting on spaces unless you quote the string.

除非您引用字符串,否则 shell 将对空格执行分词。

In order to loop over the elements in the thus created array:

为了遍历由此创建的数组中的元素:

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

回答by perreal

Another method using read:

另一种使用读取的方法:

read -a array <<< $str

回答by Benjamin Reed

I am in an unfortunate position where I have a long-standing shell script that is upgrading from internally using scalar variables to using arrays. But, users are also allowed to set those variables themselves, optionally, with a file that is sourced on startup.

我处于一个不幸的位置,我有一个长期存在的 shell 脚本,它正在从内部使用标量变量升级到使用数组。 但是,用户也可以自己设置这些变量,可以选择使用启动时提供的文件。

So, I needed to make a way to conditionally convert a scalar to an array, depending on whether the user's sourced script is declared in the new way orthe old way.

因此,我需要根据用户的源脚本是以新方式还是旧方式声明,有条件地将标量转换为数组。

My solution is overkill for the simple case above, but I wanted to document it for others looking for this solution, because it was non-trivial coming up with something that handled my use case.

我的解决方案对于上面的简单案例来说太过分了,但我想为其他寻找此解决方案的人记录下来,因为提出处理我的用例的东西并非易事。

The only way I've come up with to reliably handle all options safely is thus:

因此,我想出的安全可靠地处理所有选项的唯一方法是:

convert_array() {
        __array_name=""; 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
}

It cleanly handles all cases: existing variable, existing array, and not set at all.

它干净地处理所有情况:现有变量、现有数组和根本不设置。

Also note that while this may seem like overkill:

另请注意,虽然这似乎有点矫枉过正:

__existing_value="$(eval echo "\${$__array_name}" | sed -e 's,^[[:space:]]*,,' -e 's,[[:space:]]*$,,')"

__existing_value="$(eval echo "\${$__array_name}" | sed -e 's,^[[:space:]]*,,' -e 's,[[:space:]]*$,,')"

...it handles the case that most people are building their sourced configurations something like this:

...它处理大多数人正在构建他们的源配置的情况,如下所示:

ADDITIONAL_OPTIONS="${ADDITIONAL_OPTIONS} -Xmx2g"
ADDITIONAL_OPTIONS="${ADDITIONAL_OPTIONS} -Dsome.property=foo"

In these cases, the $ADDITIONAL_OPTIONSvariable will start with a space. If you know your inputs won't need trimming, that bit is unnecessary.

在这些情况下,$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