テキストファイルを次のように分割しています。
field1,field2,field3
xield1,xield2,xield3
dield1,dield2,dield3
gield1,gield2,gield3
これらの各列はプログラムのパラメーターになります。プログラムは各行で呼び出されます
私はループのようなものを望んでいました:
for $i in file
command $field2 -x $field3 -PN -$field1 >> output
done
このようなことをbashで達成するための最良の方法は何でしょうか?
while IFS=, read xx yy zz;do
echo $xx $yy $zz
done < input_file
これは、フィールドの数が一定であれば機能するはずです。 echo
の代わりに、コマンドを使用してください。
while
を組み込みでread
を使用する必要があります。
while IFS= read -r line;do
fields=($(printf "%s" "$line"|cut -d',' --output-delimiter=' ' -f1-))
command "${fields[1]}" -x "${fields[2]}" ... # ${fields[1]} is field 2
done < your_file_here
これがどのように機能するか
cut
ステートメントは行を受け取り、-d
で指定された区切り文字で分割します。--output-delimiter
は、cut
が選択したフィールドを表示するために使用する区切り文字です。ここでは、スペースを選択して、異なるフィールドを配列fields
に配置できるようにします。-f1-
が役立ちます。fields
にさまざまなフィールドが格納されました。構文${field[number]}
を使用して、特定のフィールドにアクセスできます。ここで、number
は、Bashでの配列のインデックス付けがゼロベースであるため、必要な実際のフィールド番号より1つ少ない値です。注
一定数のフィールドの場合
代わりに 1_CRの答え のようなものを実行できます。
while IFS= read -r line;do
IFS=, read -r field1 field2 field3 <<-EOI
$line
EOI
command "$field2" -x "$field3" ...
done < your_file_here
上記は、よりうるさいように見えますが、Bashだけでなく、POSIX準拠のシェルでも機能します。
read
を適切に設定することにより、IFS
を取得して各行を,
の配列に分割できます。
while IFS=, read -r -a input; do
printf "%s\n" "${input[0]}" "${input[1]}"
done < input.txt
したがって、上記の例では、0から始まるインデックスを使用して各配列要素にアクセスできます。
このawk
ワンライナーはあなたが望むことをします:
_awk -F, '{cmd="echo " $2 " -x " $3 " -PN " $1 ">> output"; system(cmd)}' f.txt
_
echo
をコマンドに置き換え、_f.txt
_を繰り返し処理するファイルに置き換えます。
簡単な説明:_-F,
_は_,
_を区切り文字として設定します。 cmd
はコマンドを作成し、system(cmd)
はコマンドを呼び出します。
gnu sedも使用できます。
sed infile -e 's!^\([^,]*\),\([^,]*\),\([^,]*\)$!command \1 -x \2 -PN \3!e' >> output
sコマンドのeオプションの使用に注意してください