単一変数からの複数変数の割り当てに対応するテキストの生成

単一変数からの複数変数の割り当てに対応するテキストの生成

次の値を持つ変数があります

line=dog,/path1,/path2

私が望むのは、値から変数を生成することです。つまり、dog変数にする必要があり、次の出力を取得したいと思います。

dog=/path1,/path2
dog1=/path1
dog2=/path2

同様に、line=bull,/val1,/val2次の出力が必要です。

bull=/val1,/val2
bull1=/val1
bull2=/val2

カンマで区切られた値はline3つだけです。

答え1

私はこれがあなたがしたいことだと思います:

line='dog,/path1,/path2'
IFS=', ' read -r -a dog <<< "$line"

echo "$dog"
dog
echo "${dog[1]}"
/path1
echo "${dog[2]}"
/path2 

これはシェルがbashであると仮定します。

答え2

Bash中心のソリューションは次のとおりです。

IFS=, read -r -a vars <<<"$line"
printf "%s\n" "${vars[0]}=${vars[1]},${vars[2]}" "${vars[0]}1=${vars[1]}" "${vars[0]}2=${vars[2]}"

最初の行は、$line変数をカンマに基づいて複数の部分に分割します。 2行目は内側から外側に向かいます。

  1. 最初の値(「dog」など)、等号、2番目の値を印刷します。
  2. 1等号の付いた最初の値を出力し、次に2番目の値を出力します。
  3. 等号が接尾辞で付けられた最初の値を出力し、次に23番目の値を出力します。
  4. printfこれらの3つの文字列は改行文字で区切られています。

あなたの質問と同様に、この答えも$line

入力と出力の例(前に$シェルプロンプトが来ます):

$ line=dog,/path1,/path2
$ IFS=, read -r -a vars <<<"$line"
$ printf "%s\n" "${vars[0]}=${vars[1]},${vars[2]}" "${vars[0]}1=${vars[1]}" "${vars[0]}2=${vars[2]}"
dog=/path1,/path2
dog1=/path1
dog2=/path2

printf出力をファイルに簡単にリダイレクトできます。

答え3

を使用している場合は、bash次のことができます(echo各ステップで発生する状況を示す追加ステートメントを使用)。

$ line=dog,/path1,/path2

$ newline=$(printf "%s\n" "$line" | 
            perl -n -e 'BEGIN {$count=1};
                        my ($var,@values) = split /,/;
                        print "$var=" . join(",",@values);
                        foreach (@values) {
                            printf "%s%i=\"%s\" ",$var, $count++, $_
                        }')

$ echo "$newline"
dog=/path1,/path2 dog1=/path1 dog2=/path2

$ declare $newline

$ declare | grep '^dog'
dog=/path1,/path2
dog1=/path1
dog2=/path2

perlカンマで区切るために使用されます。$line最初のフィールドはに保存され、$var残りのフィールドは名前付き配列に保存されます@values。次に、declare変数を設定するためにbashコマンドで使用するのに適した出力を生成します。

この行では二重引用符を使用せず、使用し$newlineないでください。declare二重引用符で囲むと、スペースで区切られた3つの引数のdeclare代わりに1つの引数のみが得られます。

ここで引用不足による不快な副作用は次のとおりです。declare 〜するフィールド値にスペース文字などが含まれていると失敗します。たとえばline=dog,/path /with / spaces,/path2。必要に応じて、スクリプトのprint文と文からprintf適切な参照を出力することでこの問題を解決できますperl。および/または$newline文字列の代わりにbash配列として定義されます。ここで使用されている原理/技術を十分に示したので、読者のための練習として残しておきます。

エクスポートした変数として宣言するには、次のようにします。

declare -x $newline

詳細についてはを参照してくださいhelp declare

ちなみに代わりにksh使うことができます。また、サポートされているが廃止予定と見なされます(参照)。typesetdeclaretypesetbashhelp typesetbash


最後に:個々の変数の代わりにシェル配列変数(例えば、dog[0]=/path1,/path2およびdog[1]=/path1)を使用するのが好きではありませんか?dog[2]=/path2これが彼らの存在の目的です。

答え4

このようにすることができます。私はあなたがしたように線を定義しました。次に、行の最初のカンマ区切りトークンを解析します(変数名に有効であると仮定します)。次に、最初のタグに基づいて2つの新しい変数を作成し、それを行の2番目と3番目のカンマ区切りタグに割り当てます。

line="dog,/path1,/path2"
first="$(echo "${line}" | awk -F, '{ print $1 }')"
eval "${first}1=$(echo "${line}" | awk -F, '{ print $2 }')"
eval "${first}2=$(echo "${line}" | awk -F, '{ print $3 }')"

echo "${dog1}"
/path1
echo "${dog2}"
/path2

関連情報