26

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

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

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

1
  • 2
    If your titles have no spaces, you can use: array=( $string ) (no quotes for $string). If your titles include spaces... well... it depends on how they are formed. Commented Oct 29, 2013 at 12:06

3 Answers 3

42

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.

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
Sign up to request clarification or add additional context in comments.

2 Comments

FYI, this will not work for Zsh; see zsh.sourceforge.net/FAQ/zshfaq03.html
To do in zsh to your point @anishpatel you'll need to do this : > setopt shwordsplit; carry out the command you want to do; unsetopt shwordsplit
6

Another method using read:

read -a array <<< $str

3 Comments

what does <<< do?
redirects the variable: stackoverflow.com/a/4775845/390913
What is the difference between readarray vs read -a
0

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.

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 or the 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="$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
}

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:]]*$,,')"

...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_OPTIONS variable will start with a space. If you know your inputs won't need trimming, that bit is unnecessary.

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.