表形式のデータからコマンドを一括生成する方法の比較


## 解決したい問題

以下、環境はWindowsです
複数の要素に対して同じコマンドを打ちたいこと、良くあると思います
たとえば、こんな表があるとします

| Schema  | Table   |
| ------- | ------- |
| schema1 | table11 |
| schema1 | table12 |
| schema2 | table21 |
| schema3 | table31 |
| schema3 | table32 |
| ...     | ...     |

この表で指定されたスキーマおよびテーブルに対して、`pg_dump` でダンプファイルを生成するためのコマンドを作りたい。

```作りたいもの.txt
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`

可読性は良いのですが、同じテキストエディタをすべての人が使ってるわけではないので、再利用性が少し低いです

### 解決策２: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コマンドを実行します
解決策１と同じやん！って思った方、正解ですけれど、ワンライナーで書けること、結果をクリップボードに保存できることなどCUIの強みがあります
Windowsでgitでバージョン管理してるエンジニアであればもれなくgit bashも持っているでしょうということで、再利用性も高いです

CSVの場合
```sh
sed -e 's/^\(.*\),\(.*\)\r/pg_dump mydb -t \1.\2 >db_\1_\2.sql\r/g' data.csv`
```

TSVの場合
```sh
sed -e 's/^\(.*\)\t\(.*\)\r/pg_dump mydb -t \1.\2 >db_\1_\2.sql\r/g' data.tsv
```
結果をクリップボードに保存したい場合はこんな感じです
```sh
sed -e 's/^\(.*\),\(.*\)\r/pg_dump mydb -t \1.\2 >db_\1_\2.sql\r/g' data.csv | clip
```

見てるとゲシュタルト崩壊起こしそうですね。
ワンライナーで書けるのは魅力的だけれど、可読性はかなり低いです。


### 解決策4:Powershellを使う

個人的におすすめなのがこの解決策。

CSV版
```powershell
ipcsv .\data.csv -Header @(0..1) | % {"pg_dump mydb -t {0}.{1} >db_{0}_{1}.sql" -f $_.0,$_.1}
```

文字数を犠牲にもっと可読性を上げたいならこんな感じです

```powershell
Import-Csv .\data.csv -Header @(0..1) | foreach {"pg_dump mydb -t {0}.{1} >db_{0}_{1}.sql" -f $_.0,$_.1} 
```

TSV版
```powershell
ipcsv .\data.tsv -Header @(0..1) -Delimiter "`t" | % {"pg_dump mydb -t {0}.{1} >db_{0}_{1}.sql" -f $_.0,$_.1}
```

クリップボードからTSVデータを取得して、結果をクリップボードにコピーするならこんな感じです
```powershell
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 を扱う方法まとめ