There's More Than One Way To Do It

How to run Emacs macro via CLI without remembering complex shell commands

Proof of concept


When I convert file or replace some text, if the repeat is necessary,

  1. Use unix commands
  2. Combine 1
  3. Write scripts

are standard selection routine.

Sometimes complex 2 is called as shell art.

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

Although we can understand the program if the number of commands are a few, the command with many combinations is dark magic.

To ease this pain, one of the approach is rb command, which is simplified Ruby. This approach make Option 3 close to 1 and 2.

This is useful, but command is long because it is simply Ruby. Also the speed of Ruby is slow compared with native Unix commands.

When the other engineers use option 2, in most cases, I simply use Emacs macro. If we can do this by CLI (Make Option 1 &2 rich), it's very helpful.

What is Emacs Macro?

In Emacs, we can record keyboard strokes and paly it (keyboard macro). Keyboard macro can be repeat run like the other Emacs commands using C-u.

  1. Record start: C-x (
  2. Do custome action. Using C-a(Move to head) on head ,C-n(newline) on end makes action stable
  3. Record end: C-x )
  4. Run many times:C-u <repeat number> C-x e

This concept is also available in Excel+VBA, Windows+UWSC too. Save format is long compared with Emacs Macro anyway.

Emacs operation is basically just key input, C-(Ctrl) and M-(Meta).

If we assume

  • ^A => C-a
  • ^a => M-a (Under struggle)

, escape word in only ^. Very simple.


node.js is one option but I use golang for multiplatform support and speed. Interface is the copy of grep.

$ 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

another example

$ 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

Is regex only expression for string DSL?

The most famous string DSL is probably regular expression. Regular expression is useful but main focus is pattern match. IMO, the weight is more on find than replacement.

The final purpose of text replacement is imitation of text editor. String DSL is not only regular expression. Simple expression of text editor operation can be competitor. That is my assumption.

Unix philosophy says do one thing well. Alghough Regex is very complex, we recognize regex is one operation. If we can invent simple DSL instead of shell art, that DSL will be recognized as one thing after ten years ago .