webentwicklung-frage-antwort-db.com.de

Konvertieren Sie eine Textzeichenfolge in Bash in ein Array

Wie konvertiere ich einen String in BASH in ein Array in Bash!

Ich habe eine Zeichenfolge str , die "title1 title2 title3 title4 title5" (Durch Leerzeichen getrennte Titel) enthält.

Ich möchte, dass der str in ein Array geändert wird, in dem jeder Titel in jedem Index gespeichert wird. 

11
Ayush Mishra

Um den String in ein Array zu konvertieren, sagen Sie:

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

Die Shell führt eine Wortaufteilung in Leerzeichen durch, sofern Sie die Zeichenfolge nicht angeben.

Um die Elemente in dem so erstellten Array zu überlaufen:

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

Eine andere Methode, die read verwendet:

read -a array <<< $str
1
perreal

Ich befinde mich in einer unglücklichen Position, in der ich ein langjähriges Shell-Skript habe, das von internen Skalarvariablen auf Arrays umstellt. Aber , Benutzer können diese Variablen auch selbst festlegen, optional mit einer Datei, die beim Start aufgerufen wird.

Also , ich musste einen Weg finden, einen Skalar bedingt in ein Array zu konvertieren, abhängig davon, ob das vom Benutzer bereitgestellte Skript auf die neue Weise oder auf die alte Weise deklariert ist.

Meine Lösung ist übertrieben für den einfachen Fall, aber ich wollte es für andere dokumentieren, die nach dieser Lösung suchen, weil es nicht einfach war, etwas zu finden, das meinen Anwendungsfall behandelte.

Die einzige Möglichkeit, mit der ich alle Optionen sicher handhaben kann, ist also:

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
}

Alle Fälle werden sauber behandelt: vorhandene Variable, vorhandenes Array und überhaupt nicht festgelegt.

Beachten Sie auch, dass dies zwar übertrieben wirken kann:

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

... es handhabt den Fall, dass die meisten Leute ihre beschafften Konfigurationen wie folgt bauen:

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

In diesen Fällen beginnt die Variable $ADDITIONAL_OPTIONS mit einem Leerzeichen. Wenn Sie wissen, dass Ihre Eingänge nicht getrimmt werden müssen, ist dieses Bit nicht erforderlich.

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
0
Benjamin Reed