複数のファイルがあり、それぞれに異なる列数があります。それらを変換してデータベースに挿入したい
たとえば、ファイルtest01:
0001 000000000000001 john smith 45 500
0002 000000000000002 peter jackson 20 80
0003 000000000000002 robert brown 35 100
0004 000000000000007 sarah white 40 300
私の望ましい出力は:
('0001','000000000000001','john smith','45','500'),
('0002','000000000000002','peter jackson','20','80'),
('0003','000000000000002','robert brown','35','100'),
('0004','000000000000007','sarah white','40','300');
これを実現するには、次のスクリプトを使用します。
cat test01 |awk -F'\t' '{print "('\''"$1"'\'','\''"$2"'\'','\''"$3"'\'','\''"$4"'\'','\''"$5"'\''),"}' |sed '$ s/.$/;/'
そして、それは正常に機能します。問題は、列数が異なる別のファイルを見つけた場合です。そのため、スクリプトを手動で変更する必要があります。
AWKの変数NFで列の数を取得できることはわかっていますが、この変数をスクリプトのforループと組み合わせる方法は?
私がしようとすると
cat test01 | awk '{for (i = 1; i <= NF; i++){print $i"'\'','\''"}}'
私はこの結果を得ます:
0001','
000000000000001','
john','
smith','
45','
500','
0002','
000000000000002','
peter','
jackson','
20','
80','
0003','
000000000000002','
robert','
brown','
35','
100','
0004','
000000000000007','
sarah','
white','
40','
300','
GNU sed
を使用:
$ sed -e "s/^/('/" -e "s/\t/','/g" -e "s/$/'),/" -e '$s/.$/;/' file
('0001','000000000000001','john smith','45','500'),
('0002','000000000000002','peter jackson','20','80'),
('0003','000000000000002','robert brown','35','100'),
('0004','000000000000007','sarah white','40','300');
sed
スクリプトは4つの部分に分かれています。
s/^/('/
は、行の先頭を('
に置き換えます。s/\t/','/g
は、タブを','
に置き換えます。これは、GNU sed
を必要とするビットです。他のsed
の実装では、\t
の代わりにリテラルタブを挿入します。s/$/'),/
は、行末を'),
に置き換えます。$s/.$/;/
は、最後の行の終わりにあるコンマ(のみ)を;
に置き換えます。入力ファイルがタブで区切られている場合は、以下を試すことができます。
awk -F"\t" -vq="'" -vOFS="','" '$1=$1 {print "(" q $0 q ");"}' filename
または、print関数に引用符を埋め込みます。
awk -F"\t" -vOFS="','" '$1=$1 {print "(" "\x27" $0 "\x27" ");"}' filename
最初のスクリプトで希望どおりの動作を実現するには、awkの「printf」メソッドを使用できます。 「印刷」によって置かれた改行を取り除くことを可能にします。私は推測していますが、スクリプトは次のように書き直す必要があります。
cat test01 | awk '{for (i = 1; i <= NF; i++){printf $i"'\'','\''"}; printf "\n";}'