TransWikia.com

How to get the line numbers for all matches?

Vi and Vim Asked by xiaodong huan on November 7, 2021

How can I get the line numbers of all matching strings in a buffer?
Like in this buffer, I want to get the list [1,6,50] of all line numbers with matching strings.

1:  test ....


6:  test ....

50: test ....

2 Answers

Doing two manual passes over the text is rarely needed. Most often one just does

g/^test/DoSomething

And that's enough. The reason is that :g is implemented in two passes, so it's not a problem if you, say, add a few lines after each match.

However, if you really want those numbers in a List, you can achieve this with the same pattern:

let temp = []
g/^test/call add(temp, line('.'))

Answered by Matt on November 7, 2021

A convoluted (and untested) way I sometimes use. The idea is to use map() to associate line numbers to the actual (matching) lines, then filter() to keep only the matching lines, then map() again to return only the line numbers

" Note: This code uses lambdas and vim 8.{recent} methods.
:echo getline(1, '$')->map({l, v -> [l+1, v =~ 'test']})->filter({k,v -> v[1]})->map({k,v -> v[0]})

Another convoluted approach consists in using a function that permits to apply changes as matches are found (still untested)

:let g:lines = []
:call getline(1, '$')->map({k,v -> v =~ 'test' ? add(g:lines, k+1) : g:lines})
:echo g:lines

" or 
:call map(getline(1, '$'), {k,v -> v =~ 'test' ? add(g:lines, k+1) : g:lines})

Note: we could also use :global which is much simpler (see Matt's answer) but as it messes search register and cursor position, I usually avoid it when writing plugins.

Answered by Luc Hermitte on November 7, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP