3

Let's say, I want to search for email addresses and output them to a new file. What I can do so far with a help from another discussion is this:

g/pattern/.w! >> output.txt 

but that saves whole lines where search matches occur. Is it possible to extract just the matches (with possibility for them to be multiple on one line)? I would prefer a solution (if possible) without some additional plugins or macros.

1

3 Answers 3

7

This is a bit easier with grep and the --only-matching/-o option.

grep -o 'pattern' file.txt > output.txt

You can use Vim's substitution as well:

:%s/.*\(pattern\).*/\1

This approach will affect the current buffer though. It would probably be best to copy the file first.

Note: these approachs assumes only 1 match per line

2

Peter's solution with grep -o is the way to go IMO.

Yet, for the sake of the exercise here is a 100% pure vim script solution

" prepare the result variable to be of the right type
:let res = []
" join all lines in a big string, and use `substitute` to fill the result with matches -- this is the only tricky part
:call substitute(join(getline(1,'$'), ' '), 'THE PATTERN', '\=add(res, submatch(0))', 'g')

" You can remove duplicates BTW with
:let res = uniq(sort(res))

" And save into a new file
:call writefile(res, 'FILENAME')
2

If you in Windows and don't have an access to bash commands and want to do it from VIM in any case.

g/.Low rates./-1,+2.w! >> failures.txt

Will find all lines with the pattern .Low rates. Copy 1 line before the pattern, 2 lines after, and redirect all occurrences of the pattern to a file failures.txt.

1
  • Welcome to Vi and Vim! I think you may have misunderstood the question; the OP wants to keep only the parts of the line that match the pattern. And a pure-vim solution has been provided.
    – D. Ben Knoble
    Oct 15, 2020 at 13:09

Your Answer

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

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