解決したい問題
以下、環境はWindowsです
複数の要素に対して同じコマンドを打ちたいこと、良くあると思います
たとえば、こんな表があるとします
Schema | Table |
---|---|
schema1 | table11 |
schema1 | table12 |
schema2 | table21 |
schema3 | table31 |
schema3 | table32 |
... | ... |
この表で指定されたスキーマおよびテーブルに対して、pg_dump
でダンプファイルを生成するためのコマンドを作りたい。
pg_dump mydb -t schema1.table11 >db_schema1_table11.sql
pg_dump mydb -t schema1.table12 >db_schema1_table12.sql
pg_dump mydb -t schema2.table21 >db_schema2_table21.sql
pg_dump mydb -t schema3.table31 >db_schema3_table31.sql
pg_dump mydb -t schema3.table32 >db_schema3_table32.sql
...
これは一例ですが、何かしらの表形式のデータに対して一括でコマンドを作りたくなることは、ITエンジニアをやっていると日常的に起こると思います。
この解決策はいくつか考えられますが、可読性および再利用性(≒他人に理解してもらい、やってもらう)を考えたときのベストプラクティスってなんだろな?と考え、色々比較してみました。
解決策
解決策1:テキストエディタを使う
VS Code、サクラエディタ、秀丸などを使って正規表現を使って置換する
CSVの場合
置換前: ^(.*),(.*)¥r
置換後: pg_dump mydb -t ¥1.¥2 >db_¥1_¥2.sql¥r
TSVの場合
置換前: ^(.*)¥t(.*)¥r
置換後: pg_dump mydb -t ¥1.¥2 >db_¥1_¥2.sql¥r
可読性は良いのですが、同じテキストエディタをすべての人が使ってるわけではないので、再利用性が少し低いです
解決策2:Excelを使う
個人的には好きな方法。
A1セル | |
---|---|
pg_dump mydb -t ¥1.¥2 >db_¥1_¥2.sql |
行 | B列 | C列 | 数式 |
---|---|---|---|
1 | schema1 | table11 | =SUBSTITUTE(SUBSTITUTE($A$1,'¥1',B1),'¥2',C1) |
2 | schema1 | table12 | =SUBSTITUTE(SUBSTITUTE($A$1,'¥1',B2),'¥2',C2) |
3 | schema2 | table21 | =SUBSTITUTE(SUBSTITUTE($A$1,'¥1',B3),'¥2',C3) |
4 | schema3 | table31 | =SUBSTITUTE(SUBSTITUTE($A$1,'¥1',B4),'¥2',C4) |
5 | schema3 | table32 | =SUBSTITUTE(SUBSTITUTE($A$1,'¥1',B5),'¥2',C5) |
6 | ... | ... |
こうすると、数式列に置換後の文字列がベベベっと貼り付きます。
令和の時代にまだExcel使ってんの? って煽られそうですが、業務用WinPCであればほぼ入ってるでしょうし、他人が読んでも比較的分かりやすく、再利用性も高いです。
ただ、やっぱりExcelなので、いちいちファイルを開かないといけないため、他の解決策に比べて時間がかかります。
解決策3:sedを使う
git bashやwslなどを使ってsedコマンドを実行します
解決策1と同じやん!って思った方、正解ですけれど、ワンライナーで書けること、結果をクリップボードに保存できることなどCUIの強みがあります
Windowsでgitでバージョン管理してるエンジニアであればもれなくgit bashも持っているでしょうということで、再利用性も高いです
CSVの場合
sed -e 's/^\(.*\),\(.*\)\r/pg_dump mydb -t \1.\2 >db_\1_\2.sql\r/g' data.csv`
TSVの場合
sed -e 's/^\(.*\)\t\(.*\)\r/pg_dump mydb -t \1.\2 >db_\1_\2.sql\r/g' data.tsv
結果をクリップボードに保存したい場合はこんな感じです
sed -e 's/^\(.*\),\(.*\)\r/pg_dump mydb -t \1.\2 >db_\1_\2.sql\r/g' data.csv | clip
見てるとゲシュタルト崩壊起こしそうですね。
ワンライナーで書けるのは魅力的だけれど、可読性はかなり低いです。
解決策4:Powershellを使う
個人的におすすめなのがこの解決策。
CSV版
ipcsv .\data.csv -Header @(0..1) | % {"pg_dump mydb -t {0}.{1} >db_{0}_{1}.sql" -f $_.0,$_.1}
文字数を犠牲にもっと可読性を上げたいならこんな感じです
Import-Csv .\data.csv -Header @(0..1) | foreach {"pg_dump mydb -t {0}.{1} >db_{0}_{1}.sql" -f $_.0,$_.1}
TSV版
ipcsv .\data.tsv -Header @(0..1) -Delimiter "`t" | % {"pg_dump mydb -t {0}.{1} >db_{0}_{1}.sql" -f $_.0,$_.1}
クリップボードからTSVデータを取得して、結果をクリップボードにコピーするならこんな感じです
gcb | ConvertFrom-Csv -Header @(0..1) -Delimiter "`t" | % {"pg_dump mydb -t {0}.{1} >db_{0}_{1}.sql" -f $_.0,$_.1} | scb
可読性高い!何やってるかすぐ分かる!PowershellなのでWindows端末なら漏れなく入ってる!しかもワンライナー!完璧です。
まとめ
解決策 | 可読性 | 再利用性 | ワンライナー |
---|---|---|---|
text editor | ◎ | ○ | ○ |
Excel | ◎ | ◎ | △ |
sed | △ | ◎ | ◎ |
Powershell | ◎ | ◎ | ◎ |
Powershell贔屓過ぎだって? そんなことないですよ??
なにかの参考になれば幸いです。
皆さんはどんな置換が好きですか?
参考記事
https://qiita.com/nimzo6689/items/4a6fcabc032f570de6f0
PowerShell で csv を扱う方法まとめ