複数のファイルがあり、それぞれに列数が異なります。それらを変換してデータベースに挿入したい
たとえば、ファイル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");
スクリプトは4つの部分に分かれています:
-
s/^/("/
は行頭を("
。 -
s/\t/","/g
は、タブを","
に置き換えます。これは、GNUsed
を必要とするビットです。その他のsed
実装の場合、\t
の代わりにリテラルタブを挿入します。 -
s/$/"),/
は行末を"),
に置き換えます。 -
$s/.$/;/
は行末のカンマを置き換えます;
の最後の行(のみ)。
コメント
- スクリプトを実行しますそして、" > "に何かを期待していることを示すプロンプトが表示されます
- @ user3333911以前のバージョンから、引用符が一致していませんでした。現在修正され、テストされています。
回答
入力ファイルがタブで区切られている場合は、次のことを試すことができます。
awk -F"\t" -vq=""" -vOFS="","" "$1=$1 {print "(" q $0 q ");"}" filename
または印刷機能に引用符を埋め込む:
awk -F"\t" -vOFS="","" "$1=$1 {print "(" "\x27" $0 "\x27" ");"}" filename
コメント
- 最後の行を除くすべての行の終わりにあるコンマに注意してください…
- @Kusalanandaに注意してください。
awk -F"\t" -vq="'" -vOFS="','" '$1=$1 {print "(" q $0 q "),"}' filename | sed '$s/,$/;/'
のように簡単に修正しました。より良い提案はありますか? - いいえ、'適切な修正です。
回答
最初のスクリプトで必要な動作を実現するには、awkの「printf」メソッドを使用できます。 「プリント」によって入れられた改行を取り除くことが可能になります。スクリプトは次のように書き直す必要があると思います:
cat test01 | awk "{for (i = 1; i <= NF; i++){printf $i""\"","\"""}; printf "\n";}"