Vim macros are OP
17 December 2022 #vimProblem
One day, I was editing this amazing blog, and I needed to modify something in about 50 different files. I use zola as my static site generator, so for each post, there has to be a section at the top of the markdown file containg some metadata about the post. It looks like this:
+++
title = "[HTB] Ambassador Writeup"
description = "Writeup for Ambassador, a medium machine on HackTheBox"
date = 2022-11-07
draft = true
+++
I wanted to modify it to have something like that:
+++
title = "Ambassador Writeup"
description = "Writeup for Ambassador, a medium machine on HackTheBox"
date = 2022-11-07
draft = true
[taXonomies]
tags = ["CTF", "HTB", "box"]
+++
So just add 2 new lines at the end and modify the first line. My first thought was to use utilities like sed
or awk
but this task was a bit too complicated for their use cases. Vim enters the chat:
First Step
It is important to only open the files we want to modify because the macro would mess up any other file. I'll grep
recursively in my content
directory and search for the string '[HTB]':
$ grep -Rl '\[HTB\]' content/ | xargs nvim
-R
: recursive search-l
: only print filename of matched files
We have to escape the '[' and ']' characters because they have a special meaning in regex.
We then pipe all of these filenames to xargs
to open all of them at once in nvim
.
Macro
Before doing it, make sure you have 'hidden' set to true, otherwise it will prevent us from switching buffers.
- Record a macro named 'q':
qq
- Make sure we are at the top of the file:
gg
- Delete '[HTB]' in title:
/[<Enter>df
(there is a space at the end) - Go to the second '+++':
/+++<Enter>
- Write the new stuff one line above:
O<text>
- End the macro:
q
- Execute macro in all buffers:
:bufdo normal @q<Enter>
And just like that, all of the files have been modified. Vim once again proving it is the best text editor on the planet.