次の値を持つ変数があります
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つの文字列は改行文字で区切られています。
あなたの質問と同様に、この答えも$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
使うことができます。また、サポートされているが廃止予定と見なされます(参照)。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