25

In less, can you search using / for a pattern that contains a carriage return and newline? I know your pattern can end with a line using $ (from How do I include newlines in a search in less?), but I need the pattern to match text that spans multiple lines.

I tried \n, but that only searches for the n character.

yonran
  • 652
  • 1
  • 9
  • 14
  • Have you tried `\n+` for 1 or more newlines? – Brock Hensley Jan 17 '14 at 01:45
  • Which Linux distribution, and do you have defined the environment variable "LESS" ? – harrymc Feb 23 '15 at 12:59
  • @harrymc How would that help with multiline search? – sashoalm Feb 25 '15 at 18:54
  • Gathering information. – harrymc Feb 25 '15 at 19:29
  • I fear the answer for less must be no, but if you are looking for other ways to search this has been discussed [here](http://unix.stackexchange.com/questions/10226/multiline-pattern-match-using-sed-awk-or-grep), pcregrep looks the easiest solution. – gogoud Feb 25 '15 at 23:05
  • 2
    This is not possible, based on a review of the source code for `less` (`search.c:search_range()`). The search/match operation is performed on a single newline-delimited line at a time, so you cannot match across line boundaries. See `line.c:forw_raw_line()` for the implementation of "readline" as called by `search_range`. – zackse Feb 26 '15 at 05:50
  • 1
    Aside, review less release notes for options - Google search site:greenwoodsoftware.com inurl:news – Cymatical Oct 07 '21 at 16:00

3 Answers3

10

It is not possible to match across line boundaries, because the search function in less operates on a single newline-delimited line at a time. This is the case regardless of the system regex implementation (GNU, POSIX, PCRE, etc.).

Please note that I couldn't find an official source repository for the mainline development of less, but for purposes of code review here, the links that follow are from the FreeBSD contrib tree.

See search.c:search_range() for the implementation of the search operation. The loop therein calls line.c:forw_raw_line() to retrieve the next newline-delimited block of content. That block is passed to match.c:match_pattern() where the search pattern (regular expression) is executed.

To match across multiple lines, you'll need to use a different tool. One option is to drop into your editor and use its search capabilities as suggested by others. You can invoke the editor by pressing v in less.

zackse
  • 622
  • 4
  • 8
  • 1
    Official source code of _less_ can be found at https://github.com/gwsw/less or http://www.greenwoodsoftware.com/less/download.html#source – Piotr Dobrogost Nov 21 '20 at 17:12
  • Wow, github page for LESS is under 500 stars. Maybe visit and give the authors credit? Donations? From there maybe some work on multiline is possible. – Cymatical Oct 07 '21 at 15:54
6

Not sure how to do it in less, but you can accomplish the same in vim.

http://vim.wikia.com/wiki/Search_across_multiple_lines

/PATTERN1\\_.\\{-}PATTERN2

The atom \\_. finds any character including end-of-line. The multi \\{-} matches as few as possible.

Kevin Panko
  • 7,346
  • 22
  • 44
  • 53
Vam
  • 69
  • 1
  • 2
  • 3
    This does not answer the question, however, since it is about less, not vim. It should be a comment. – sashoalm Feb 22 '15 at 06:47
  • 2
    @sashoalm It's still an attempt to answer, so I'd vote it down, and move on. People searching for a solution may not be bound to use one tool specifically. – slhck Feb 22 '15 at 13:50
2

less is using ed regex syntax and it does not support multiline matching unfortunately.

https://www.gnu.org/software/gnulib/manual/html_node/ed-regular-expression-syntax.html#ed-regular-expression-syntax

I was hoping to find that as well, or at least find if this syntax bit was used in less:

RE_DOT_NEWLINE If this bit is set, then the match-any-character operator matches a newline; if this bit isn’t set, then it doesn’t.

So I can use .+ pattern to match newlines. But no, it doesn't.

stimur
  • 181
  • 1
  • 4
  • _less is using ed regex syntax_ – that is not true. From `man less`: _The pattern is a regular expression, as recognized by the regular expression library supplied by your system._ – Piotr Dobrogost Nov 23 '20 at 00:47