How do I search or substitute only within specific columns of text in Vim?
Answer
\%>20c
Explanation
The \%Nc, \%>Nc, and \%<Nc atoms let you anchor a search pattern to a specific column position. This makes it possible to match text only when it appears at, after, or before a given column — a powerful but rarely-used feature of Vim's regex engine.
How it works
\%20c— match only at column 20\%>20c— match only after column 20 (i.e., from column 21 onward)\%<20c— match only before column 20 (i.e., up to column 19)
Column numbers are 1-based and count byte positions by default. Combine the atom with a pattern to restrict where a match can occur:
/\%>40cfoo
This finds foo only when it starts past column 40 — ignoring any occurrence of foo in the first 40 columns.
Example
Suppose you have a log file where timestamps occupy columns 1–24 and the message starts at column 25. To highlight the word ERROR only in the message field (not accidentally in a timestamp):
2024-01-15 10:42:00 UTC ERROR something failed
/\%>24cERROR
Or to substitute only within columns 25–80:
:%s/\%>24c\%<81cERROR/WARN/g
Tips
- Combine
\%>Ncand\%<Mcin a single pattern to create a column range. - The byte-column
\%cand character-column\%vvariants exist:\%vrespects multi-byte characters and'virtualedit', making it the right choice for unicode-heavy buffers. - This works inside
:substitute,:global, and any other command that accepts a search pattern.