
このような値を持つ変数があります
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 行目は、内側から外側に向かって作業します。
- 最初の値(例:'dog')、等号、次の2つの値を出力します。
- 最初の値に
1
等号をつけて出力し、次に2番目の値を出力します。 - 最初の値に
2
等号をつけて出力し、次に3番目の値を出力します。 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 配列として定義することもできます。ここで使用されている原則/テクニックについては既に十分に示したので、読者の練習問題として残しておきます。print
printf
perl
$newline
エクスポート変数として宣言する場合は、以下を使用します。
declare -x $newline
help declare
詳細については、を参照してください。
ちなみに、 では、の代わりにksh
を使用できます。 も サポートされていますが、廃止されていると見なされています (の を参照)。typeset
declare
typeset
bash
help typeset
bash
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