My specific case is a text document that contains lots of text and IPv4 addresses. I want to remove everything except for the IP addresses.
I can use :vglobal<
This effect can be accomplished by using sub-replace-special substitution and setreg()
linewise
:let @a=""
:%s//\=setreg('A', submatch(0), 'l')/g
:%d _
:pu a
:0d _
or all in one line as such:
:let @a=""|%s//\=setreg('A', submatch(0), 'l')/g|%d _|pu a|0d _
Overview: Using a substitution to append each match into register "a" linewise then replace the entire buffer with the contents of register "a"
Explanation:
let @a=""
empty the "a" register that we will be appending into%s//\=setreg('A', submatch(0), 'l')/g
substitute globally using the last pattern\=expr
will replace the pattern with the contents of the expressionsubmatch(0)
get the entire string of what just matchedsetreg('A', submatch(0), 'l')
append (note: the capital "a") to @a the matched string, but linewise%d _
delete every line into the black hole register (aka @_)pu a
put the contents of @a into the buffer0d _
delete the first lineConcerns:
%s/<pattern>/\=setreg('A', submatch(0), 'l')/g
For more help
:h :s\=
:h :let-@
:h submatch()
:h setreg()
:h :d
:h :p
Assuming <ip>
is your regex to match an IP address, I presume you could do something like :
:%s/.\{-}\(<ip>\).*/\1/g
where \1
is the first matched group (the address alone), and .\{-}
used for non-greedy matching.
:set nowrapscan
:let @a=""
gg0qac/\v(\d{1,3}\.){3}\d{1,3}<CR><CR><Esc>//e+1<CR>@aq@adG
Explanation:
set nowrapscan
disables ability to seek «past the end of file».let @a=""
: empty the a register.gg0
: go to the first column (0) of the first line (gg).qa
: start writing macros.c/{pattern}<CR>
: change until pattern.c{motion}<CR><ESC>
: replace text with newline (here {motion}
is /{pat}<CR>
).//e+1<CR>
: search for last pattern, go one character left past its end (wraps around a newline, but if your lines looks like this: IP<newline>IP
, there may be problems).@a
: execute @a
macros (it is empty when you are recording it, but when you are finished it will repeat steps 1-7 until it gets an error).q
: end recording @a
.@a
: execute @a
macros.dG
: delete to the end of file.In short, I'm looking for a way to do this without leaving vim
Easy enough:
:1,$! grep --extended-regexp --only-matching --regexp="([0-9]{1,3}\.){3}[0-9]{1,3}"
(though I actually voted up icecrime's substitution answer)