3

When running through a log file, I will catch a log that's bad, and I want to search around that line for other lines that will match search parameters.

Frequently the log files are very long, and the words I'm searching for are bound to knock me out of my current context.

Is there a way to give the search a range, say 200 lines in any direction (directional would be nice too, only above/only below), so that my search is restricted to relevant context?

1
  • 1
    There are anchors for lines and such, but I can’t remember their exact usage. Check :help pattern. There are also plugins (Narrow Region comes to mind) to let you edit a small portion of the file.
    – D. Ben Knoble
    Commented Feb 21, 2019 at 4:57

3 Answers 3

7

Just visually select the lines within which you want to search for the pattern, i.e. visually select those lines what you're referring to as "context". Then get out of visual mode with <esc>. Then search using /%Vpattern, which will restrict the search to the most recent visual selection. For more info, see :h /\%V.

Edit For even more info, read the whole :h pattern.txt.

0
5

The existing answer which suggests using Visual mode and \%V is good. But since you mentioned line ranges and directional searches I figured it worth mentioning a couple other options, one of which allows relative line ranges.

Absolute line ranges in search can be specified with the \%l pattern atoms \%>###l and \%<###l.

Example:

/\%>100lfoo\%<200l

This will search for "foo" between lines 100 and 200.

Searching the next 200 lines starting with, let's say, a current line number of 50:

/foo\%<250l

If you wanted to do something like that programmatically, in a mapping for example, this would do the same thing but for any current line number:

:exe '/foo\%<' . (line(".") + 200) . 'l'

Note that these operations are exclusive. Referring to the first example, \%<200l means "less than 200" just like the < suggests so use /\%>99lfoo\%<201l if you want to search lines 100 and 200 as well.*


What if you want to use relative line ranges without resorting to anything programmatic? By relative I mean a range like -10,+20 (start 10 lines before the current line and end 20 lines beyond it). For that you'll need to use a bit of a trick: the substitute command with the c flag (normally used to manually confirm each potential substitution).

Example:

:-10,+20s/foo//gc

Upon a match you will be asked to enter a one-character command that determines what happens next. Under typical circumstances you'd be deciding whether to do the substitution or not but in this case only two commands are of interest to us: n to continue searching (without substitution!) and q to quit searching.

You can, of course, use this method for absolute line ranges, too, if you prefer it to the \%l searches described above.

0

There's an excellent plugin called NrrwRgn that I don't see mentioned often (written by Christian Brabandt), which allows you to open a separate split containing a section of your current buffer with its :NR command.

To split out the 200 lines above and below the cursor you can pass it a range:

:-200,+200NR

You can then run regular searches with /, or indeed any other operations, such as global find-and-replaces :%s, or :global commands: any edits you make will be applied to your original buffer when you :write them.

I don't use it often, but I'm always glad I have it when I need it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.