3.2 KiB
Quick help
for f in *.html; do nvim -Nes "$f" < ex_commands; done
for f in "$(rg -l homu)"; do nvim -Nes "$f" < ex_commands; done
for f in $(fd -tf -e html); do
nvim -Nes <<'EX'
g/^Stl/exe "norm! cStyle: new\<CR>\<esc>"
$ | a
# ex: ff=unix:
.
wq
EX
done
Batch editing with ex
Ever needed to apply the same edit to several files? Well ex-mode is the only generalized solution for this
Ex-mode is vim's equivalent of ed
and ex
is symlinked as vim -e
on many
systems. Use the -N
flag for a more familiar experience. Enter this mode while
in vim with gQ
. Using the ex
executable is slightly different from neovim's
implementation, notably neovim doesn't echo back with nu
and p
ex file
vim -Nes file
Ex-mode uses vim's command-mode syntax, which is similar though different from visual mode
:21 Goes to line 21. ^ and $ are for the first and last line
:10,20d Deletes lines 10 through 20, inclusive on both ends
:u[ndo] Undoes the last action
:mark a Makes a mark at a. From vim
:ka Also makes a mark at a. From ex
:'a Go to mark a
:g/re/p Globally exectute a command on lines with /re/
:v/re/p Inverse of :g. Executes on all lines without /re/
:3,6co$ Copy lines [3,6] to the end of the document
:3m6 Move line 3 to line 6
:z=3 Pretty print lines in [-2,+2]
:norm! @l Execute keystrokes, if all else fails
Several commands can be chained with |
, similar to ;
in bash
:g/bash/exe "normal! cfish\<esc>" | undo | nu
Changes every line with "bash" to "fish", undoes that, then prints the line
:g/string/nu | g/num/nu
Does NOT print all the lines with string
or num
. This prints all the lines
with string
then reprints them if they also have num
. :g
only uses a new
line to delimit its commands from the next set!
Batch editing styles:
- Here-string: For only one command, here-strings are a quick and easy choice
for f in $(find ~/); do nvim -Nes <<<"%s/re/p | wq"; done
- Here-ansi-c-string: Allows including c-style escape sequences
for f in $(find ~/); do vim -Nes <<< $'%s/re/nu\nwq'; done
- Here-documents: The best choice for quick batch edits
for file in $(fd -at type subs_); do
nvim -Nes $file <<'DOC'
g/^Stl/exe "norm! cStyle: new\<CR>\<esc>"
$ | a
# ex: ff=unix:
.
wq
DOC
done
for file in ~/.bash*; do vim -Nes $file <<EOF
a
# ex: set syntax=bash:ff=unix:
.
wq
EOF
done
- Sourced documents: Better for recurring batch edits. Similar to
nvim -S
fd -a subs_ -x ex < change_font
fd -a subs_ -x nvim -Nes < change_font
for f in *.html; do nvim -Nes "$f" < ex_commands; done
for f in "$(rg -l homu)"; do nvim -Nes "$f" < ex_commands; done
Best practices
Use -t file
in fd
, otherwise ex
may stop when it hits a directory
Unless you're really confident, always use files to store commands, then first try them out on copies of files you'd like to edit. It's often hard to debug an edit in advance and there's no undo
Batch editing manually
This isn't really a batch edit... though it's worth mentioning
fd -t file . -X rg --files-with-matches 'ex:' | xargs -o vim