web-dev-qa-db-ja.com

bashのテキスト文字列を配列に変換する

BASHでこのような文字列をbashの配列に変換するにはどうすればよいですか?

"title1 title2 title3 title4 title5"(スペースで区切られたタイトル)を含む文字列strがあります

Strを、各インデックスに各タイトルを格納する配列に変更します。

14
Ayush Mishra

文字列を配列に変換するには、次のようにします。

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

シェルは、文字列を引用しない限り、スペースでWord分割を実行します。

このように作成された配列の要素をループするために:

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

Readを使用する別の方法:

read -a array <<< $str
1
perreal

残念ながら、内部的にスカラー変数を使用する方法から配列を使用する方法にアップグレードする長年のシェルスクリプトがあります。 ただし、ユーザーは、起動時にソースとなるファイルを使用して、オプションでこれらの変数を自分で設定することもできます。

So、ユーザーのソーススクリプトが新しい方法で宣言されているかどうかに応じて、スカラーを条件付きで配列に変換する方法を作成する必要がありましたor古い方法。

私のソリューションは上記の単純なケースではやり過ぎですが、このソリューションを探している他の人にそれを文書化したいと思いました。

したがって、すべてのオプションを安全に確実に処理するために私が思いついた唯一の方法は、次のとおりです。

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