zshの一括ファイルリネームコマンド zmv のGolang版を作っています。
Golangについてもgithubについても、ベストプラクティスがわからないので、コメント歓迎です。
先日、zsh の zmv というコマンドの話題を見かけました。
昔、zsh ユーザでしたが、bashの機能が増えてきてから、もう何年も bashをそのまま使ってます。
zmvを使ったことはないけど、便利そうなのでbashでも使えるように(あわよくばWindowsでも)、Golangに移植してみたいと思っていろいろ調べました。
まずは、zmvのソースをチェック!
https://github.com/zsh-users/zsh/blob/master/Functions/Misc/zmv
コメント部分を抜かすと150行程度のコンパクトなzshシェルスクリプトのソースコード。
パッと見、「bashスクリプトで書き換えれば簡単にbashで動くようになるんじゃないの?」と思ってしまったのですが、よく見てみると呪文多めで、コンパクトなコードはzshの魔拡張の賜物であることを理解しました。
具体的には、zshの正規表現の拡張、変数展開の拡張、さらにオプションにより振る舞いが変わる数々の機能…
bashへの移植は、この150行のzshスクリプト以外のbashには存在しないものも一緒に、bashスクリプトに移植が必要があることに気づき、bashへの翻訳は諦めました。
結局、Golangの勉強として、Golang版zmvを作ってみることにしました。
Golangに移植するにしても、zmvのzshスクリプトを翻訳することを目指すとzshの機能が強力すぎて手に負えないので、部分的には割り切ることにしました。
基本方針としては、
- Golangで実装する。
- zmvに存在するオプションはできる限り、そのまま指定可能となるようにする。
- 実際のファイル移動は、外部コマンド呼び出しで実行する。
- 宛先パターン指定の引数の、$1 などを指定する時に、${(L)1} などの変数展開時のzsh由来の変換機能は対応しない。
としてみます。
zsh(zmv)ユーザが、zshが入ってない環境を使う時に、zmvとして使えるコマンドを作りたいです。
早速、Golangのpath/filepath の Glob関数が、** を使ったサブディレクトリの再帰検索に対応していないという問題がありましたが mattnさんのglob拡張のgo-zglobを使わせてもらうことにしました。ありがとうございます。
まだ、アルファ版にも逹っしていない状態ですが、ゆっくり実装していきたいです。
Golangについてもgithubについても、ベストプラクティスがわからないので、コメント歓迎です。