NFおよびforループを使用してスクリプトを最適化する方法

NFおよびforループを使用してスクリプトを最適化する方法

複数のファイルがあり、それぞれの列数が異なります。データベースに挿入するために変換したいです。

たとえば、ファイル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','

答え1

入力ファイルがタブで区切られている場合は、次のことを試すことができます。

awk -F"\t" -v q="'" -v OFS="','" '$1=$1 {print "(" q $0 q ");"}' filename

または、印刷機能に引用符を挿入してください。

awk -F"\t" -v OFS="','" '$1=$1 {print "(" "\x27" $0 "\x27" ");"}' filename

答え2

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つの部分に分かれています。

  1. s/^/('/行の先頭を('
  2. s/\t/','/gタブをに交換してください','。 GNUが必要な部分ですsed。他のsed実装では、代わりにリテラルタブ文字を挿入してください\t
  3. s/$/'),/行の終わりをに置き換えます'),
  4. $s/.$/;/最後の行の終わりにあるカンマを(のみ)に置き換えます;

答え3

初期スクリプトで必要なものと同じ動作を達成するには、awkの "printf"メソッドを使用できます。 「print」で配置された改行文字を削除できます。私の考えでは、スクリプトを次のように書き直す必要があるようです。

cat test01 | awk '{for (i = 1; i <= NF; i++){printf $i"'\'','\''"}; printf "\n";}'

答え4

私の試みは次のとおりです...

私のステートメントはcat、awk、sedの3つの部分で構成されています。

awkとsedステートメントは間違いなく改善することができますが、まだ学んでいます。 test01をtest2.txtに変更しました。

cat test2.txt | awk -F "\\t| " 'BEGIN {ORS=""}{print "("}{ORS=","}{for (i = 1; i <= NF; i++){print "'\''"$i"'\''"}}{print ")\n"}{ORS=""}' | sed 's/,)/),/' | sed 's/^,//' | sed '$ s/),/);/'

関連情報