How do I anchor a Vim search pattern to match only at the very start or end of the entire file?
Answer
\%^ and \%$
Explanation
Vim's ^ and $ anchors match the start and end of a line, but sometimes you need to match the very beginning or very end of the entire buffer. The atoms \%^ and \%$ are buffer-level anchors that match these positions regardless of which line you are on.
This is useful for substitutions or searches that should only act once at the file boundaries — for example, inserting a header at the top or a footer at the bottom using a pattern guard.
How it works
\%^— matches only at the very start of the buffer (position 0, before any content)\%$— matches only at the very end of the buffer (after the last character)- Both work in search
/, substitute:s, and:globalcommands - These are zero-width atoms — they consume no characters, just assert position
Example
Add a shebang line only if the file doesn't already start with one:
:if getline(1) !~ '^#!'
: execute "normal! gg0O#!/usr/bin/env bash\<Esc>"
:endif
Alternatively, use \%^ in a substitute to prepend text to the file:
:%s/\%^/# Generated file — do not edit\r/
Match and remove a trailing newline at the very end of the file:
:%s/\n\%$//
Tips
- Use
\%^in:globalto detect an empty buffer::g/\%^\%$/echo 'empty' - Combine with
\%$to match the entire buffer content as a single pattern - Unlike
^and$, these anchors are unaffected by the\v(very magic) flag