やりたいこと
動的に生成されたID一覧があって、それをSQLのIN句のパーツとして使いたい。
target_id_list.txt
10001
10002
10003
10004
10005
target_id_list_string.txt
a0001
a0002
a0003
a0004
a0005
これを id in(10001,10002,10003,10004,10005) みたいな感じにしたい。
特に、IDが文字列の場合はシングルクォートで囲ったりしたい。
さらに、Redshiftに対してunloadするクエリにも使いたい。
エクセルやテキストエディタに貼り付けて置換をするとソウルジェムが少し淀むので、コマンドで、主にLinux上で完結できる方向にしたい。
地味に襲ってくる課題
- 普通にループすると最初or最後にカンマが付いてしまうので除去が必要
- 中身が文字列だと、シングルクォートが必要
- Redshiftにunloadとして投げる場合にシングルクォートにエスケープが必要
解決ステップ
"1. 普通にループすると最初or最後にカンマが付いてしまうので除去が必要" への対処
awk先生お願いします!
[sample@test tmp]$ awk '{ if(NR==1){print " " $1 }else{print "," $1 } }' target_id_list.txt
10001
,10002
,10003
,10004
,10005
2行目以降はカンマをつける、という処理。
NRで行数の判定が出来るので、比較的きれいに書ける。
"2. 中身が文字列だと、シングルクォートが必要" への対処
[sample@test tmp]$ awk '{ if(NR==1){print " \047" $1 "\047" }else{print ",\047" $1 "\047"} }' target_id_list_string.txt
'a0001'
,'a0002'
,'a0003'
,'a0004'
,'a0005'
awkでは、シングルクォートは\047で表現可能(初見殺し)。
※参考
http://gauc.no-ip.org/awk-users-jp/blis.cgi/DoukakuAWK_080
"3. Redshiftにunloadとして投げる場合にシングルクォートにエスケープが必要" への対処
[sample@test tmp]$ awk '{ if(NR==1){print " \\\047" $1 "\\\047" }else{print ",\\\047" $1 "\\\047"} }' target_id_list_string.txt
\'a0001\'
,\'a0002\'
,\'a0003\'
,\'a0004\'
,\'a0005\'
Redshiftでunloadをする場合、シングルクォートは\でエスケープが必要となるため、上記に加えさらに\\ を追加して \\\047 とする。
余談
上記の文章をQiitaの記事としては以下の通りとなる。
上記に加えさらに\\\\ を追加して \\\\\\047 とする。
以上、エスケープ祭り会場からお送りしました。