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

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

このような値を持つ変数があります

line=dog,/path1,/path2

私が望んでいるのは、値から変数を作成することです。つまり、dog変数を作成して、以下の出力を取得したいのです。

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

同様にline=bull,/val1,/val2以下の出力が必要です

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

lineカンマで区切られた値は 3 つだけであることに注意してください。

答え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. 最初の値に2等号をつけて出力し、次に3番目の値を出力します。
  4. printf改行で区切られた 3 つの文字列。

この回答は、あなたの質問と同様に、 に 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ます。次に、変数を設定するための bash コマンドで使用するのに適した出力が生成されますdeclare

行内では二重引用符$newlineで囲まないでくださいdeclare。二重引用符で囲むと、declareスペースで区切られた 3 つの引数ではなく、1 つの引数のみが取得されます。

ここで引用がないことで生じる不快な副作用の一つは、declare 意思フィールド値のいずれかにスペース文字などが含まれている場合は失敗します。例: 。必要に応じて、スクリプト内のステートメントとステートメントline=dog,/path /with / spaces,/path2から適切な引用符を出力することでこれを修正できます。また、文字列ではなく bash 配列として定義することもできます。ここで使用されている原則/テクニックについては既に十分に示したので、読者の練習問題として残しておきます。printprintfperl$newline

エクスポート変数として宣言する場合は、以下を使用します。

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

関連情報