algonote

There's More Than One Way To Do It

シェル芸を覚えたくないのでEmacsのマクロをコマンドラインで実行するemacroをつくった

Proof of concept

f:id:hiromichinomata:20200429221317p:plain:w200

前口上

簡単なファイルの変換やテキストの変換をする際、行単位でやることが同じ場合、

  1. unixのコマンド、ツールで対応
  2. 1を組み合わせる
  3. スクリプトを書く

が思考ルーチンの標準的な流れとして(個人の意見です)、2のクエリが複雑化したものはシェル芸と呼ばれる.

参考: 【シェル芸人への道】シェル芸人の第一歩 - Qiita

組み合わせるコマンドが少ないうちは解読しやすいのだが、組み合わせが増えるにつれ解読が難しくなり黒魔術となる.

このつらみを解消するためのアプローチの一つとして例えばrbコマンドがあり、これはRubyでできることを簡易な記法でできるようにしたアプローチ(3を1,2に近づける)。

ja.algonote.com

これはこれで便利なのだが、DSLとしてはRubyの記法並みには長くなってしまうのと処理速度がUnixのコマンドと比べると遅い。

個人的には2ですることの大部分はファイルが軽いならEmacsのマクロでやってしまうことが多く、それをCLI化できれば(1,2を3に近づける)、やりたいことに近くなるのではというのが今回のモチベーション。

Emacsのマクロとは

Emacsではキーボードの操作を記録することができ、それを再度実行もできる(キーボードマクロ)。マクロ実行のコマンドも他のEmacsの操作と同じく C-uで複数回実行可能

  1. 記録スタート: C-x (
  2. 1行あたりの操作。頭にC-a(行頭移動), 最後にC-n(改行)を入れると安定する
  3. 記録終了: C-x )
  4. 繰り返し実行:C-u <回数> C-x e

こう言った概念はExcel+VBAやWindows+UWSCなどでもあるが保存フォーマットはコマンドの羅列で長め。

Emacsの操作は基本的に通常のキー入力とC-(Ctrl)とM-(Meta)との組み合わせなので

  • ^A => C-a
  • ^a => M-a (模索中)

とすれば特殊文字^だけで表現可能でとても短い

実装してみる

node.jsと悩んだがマルチプラットフォームや速度重視でgolangで. インターフェイスはgrepに合わせる

github.com

$ cat test/sample.csv
2020-04-01 01:23,user01,male,17
2020-04-01 02:34,user02,female,27
2020-04-01 03:45,user03,male,37

$ grep female test/sample.csv
2020-04-01 02:34,user02,female,27

$ emacro '^S,user^D^D' test/sample.csv
2020-04-01 01:23,user,male,17
2020-04-01 02:34,user,female,27
2020-04-01 03:45,user,male,37

もう少し遊んでみる

$ emacro "as^Adf" test/sample.csv
dfas2020-04-01 01:23,user01,male,17
dfas2020-04-01 02:34,user02,female,27
dfas2020-04-01 03:45,user03,male,37

$ emacro "as^F^Fdf" test/sample.csv
as20df20-04-01 01:23,user01,male,17
as20df20-04-01 02:34,user02,female,27
as20df20-04-01 03:45,user03,male,37

文字列のDSLは正規表現だけでなくてもいいのでは

文字列の処理機構として多くの言語で使われているのは正規表現ですね。正規表現は便利な反面パターンマッチが主目的なのでどちらかといえば置換より検索にフォーカスしている(個人の意見です)。

本質的に文字列処理は人間がテキストエディタで編集する操作の自動化。文字列のDSLは正規表現とは違った別の形があってもいいのでは?それはテキストエディタ操作の簡潔記法なのでは? と言うのが今回の仮説。

Unixの哲学として一つのことをうまくやるは正しいが、正規表現は割合複雑な処理をしている割には1つのこととして認知されている。シェル芸の組み合わせでできることを上手く表現できるDSLを発明することができれば10年後、それが1つのこととして認知されると面白いなと思う今日この頃です

github.com