variable_list="
any:any:-a -b -c any
one:one:-c -b -f -m mul
mul:one:-c -b -f -m mul
"
for f in `echo $variable_list`
do
c1=`echo $f | cut -d':' -f1`;
c2=`echo $f | cut -d':' -f2`;
c3=`echo $f | cut -d':' -f3-`;
echo "c1==>$c1 and c2==>$c2 and c3==>$c3";
#exit 0; ###I made mistake here
done;
予想出力:
c1==>any and c2==>any and c3==>-a -b -c any
c1==>one and c2==>one and c3==>-c -b -f -m mul
c1==>mul and c2==>one and c3==>-c -b -f -m mul
編集1:
私はスクリプトが愚かであることに気づき、exit 0
実際にこのようなスクリプトがたくさんあるので、最初の反復では最初の行だけをテストしました。それは必要な方法で動作します。
variable_list
入力形式/方式を変更せずに保持して上記の出力を得ることはできますか?
(私はbashを使用しています)
答え1
問題はデータの空白に関連しています。シェルは文字列をすべての空白の単語に分割し、ループはfor
単語を繰り返します。
variable_list
(配列に置き換えない解決策については、この回答の最後の部分を参照してください。)
代わりに適切な配列を使用してください。
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
for var in "${variable_list[@]}"; do
c1=$( cut -d':' -f1 <<<"$var" )
c2=$( cut -d':' -f2 <<<"$var" )
c3=$( cut -d':' -f3- <<<"$var" )
printf 'c1==>%s and c2==>%s and c3==>%s\n' "$c1" "$c2" "$c3"
done
配列を使用すると、改行や他の文字を使用して区別することなく、個々の変数のセットに独自の配列項目としてアクセスできます。
コードはまた、「here-strings」を使用して(パイプではなく)bash
文字列を送信します。cut
echo
またはより効果的に、
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
for var in "${variable_list[@]}"; do
IFS=':' read -r c1 c2 c3 <<<"$var"
printf 'c1==>%s and c2==>%s and c3==>%s\n' "$c1" "$c2" "$c3"
done
IFS
コロンを設定すると、入力はコロン(スペース、タブ、改行の代わりに)に分割されますread
。read
上記の引用はすべて重要です。二重引用符がない場合、シェルはの値と3つの変数に対して単語分割とファイル名の一致を実行しvariable_list
ますvar
。c
関連:
あなたが追求するのが特定の出力であるならば、不正行為をするかもしれません。
variable_list=(
"any:any:-a -b -c any"
"one:one:-c -b -f -m mul"
"mul:one:-c -b -f -m mul"
)
( IFS=':'; set -f; printf 'c1==>%s and c2==>%s and c3==>%s\n' ${variable_list[@]} )
これは、設定および()シェルオプションがスクリプトの残りの部分に影響を与えないように、サブシェルprintf
で実行されます。ここにコロンを設定すると、シェルが拡張されます。IFS
-f
noglob
IFS
引用しない variable_list
配列は3つのグループに分かれており、各グループには3つのパラメータがありますprintf
。 printf
最初の3つのパラメータは対応する書式文字列に従って印刷され、すべてのパラメータが処理されるまで書式は3つのパラメータの次のセットに再利用されます。
これにより、ファイル名のワイルドカード文字がある場合は、引用set -f
符のない拡張子がファイル名のグロービングをトリガーするのを防ぐことができます。variable_list
改行で区切られた文字列を使用してください。
variable_list="
any:any:-a -b -c any
one:one:-c -b -f -m mul
mul:one:-c -b -f -m mul"
while IFS= read -r var; do
IFS=':' read -r c1 c2 c3 <<<"$var"
printf 'c1==>%s and c2==>%s and c3==>%s\n' "$c1" "$c2" "$c3"
done <<<"$variable_list"
これは、ファイルからのように文字列からデータを読み込みます。
関連:
答え2
awkを使用して出力を取得できます。
echo "$variable_list" | awk -F: '
{
sub("^ ","")
for(i=1;i<=NF;i++)
sub(/^/,"c" i "==>",$i)
}1' OFS=" and "