あるディレクトリ以下で特定のパターンにヒットする行を全て削除する - $shibayu36->blog;に引き続き、やり方を模索してみた。
たとえばgolangを使っていて、ある処理をt.Cleanupに寄せたので対応するdeferを全部消したい時がある。
// StartHogeHelperの中でt.Cleanupを使って自動でhogeHelper.Close()を呼ぶことにした hogeHelper := StartHogeHelper(t) // この行を消したい defer hogeHelper.Close()
これはつまり「StartHogeHelperを呼んだ次の行でdeferを呼んでいたらdeferの行を削除する」と言い換えられる。もちろんこのやり方だと間違ったものも削除することもあるが、そこは手動で直すとして、ひとまず大多数を自動削除したい。
awkを使って実現する。また効率化のためgit grepを利用する。
git grep -l StartHogeHelper | xargs awk -i inplace '/StartHogeHelper/ {print; getline; if ($0 !~ /defer/) print; next} 1'
- git grep -lを使ってStartHogeHelperを使っているファイル名を取得
- xargsでファイル名を一つずつawkに渡す
- awk -i inplaceでファイル自体をreplaceする
/StartHogeHelper/ {print; getline; if ($0 !~ /defer/) print; next} 1
- StartHogeHelperにマッチしたら
- まずその行をprint
- getlineで次の行を取得
- deferがあった時だけその行をprint。そうでなければその行を捨てる
- 1を最後に使うとStartHogeHelperにマッチしない行はそのまま出力してくれる
こんな感じで一斉削除できて便利でした。