Dean
Dean

Reputation: 9128

How do you delete everything but a specific pattern in Vim?

I have an XML file where I only care about the size attribute of a certain element. First I used

global!/<proto name="geninfo"/d

to delete all lines that I don't care about. That leaves me a whole bunch of lines that look like this:

<proto name="geninfo" pos="0" showname="General information" size="174">

I want to delete everything but the value for "size." My plan was to use substitute to get rid of everything not matching 'size="[digit]"', the remove the string 'size' and the quotes but I can't figure out how to substitute the negation of a string.

Any idea how to do it, or ideas on a better way to achieve this? Basically I want to end up with a file with one number (the size) per line.

Upvotes: 2

Views: 1396

Answers (2)

Zsolt Botykai
Zsolt Botykai

Reputation: 51693

:v:size="\d\+":d|%s:.*size="\([^"]\+\)".*:\1:

The first command (until the | deletes every line which does not match the size="<SOMEDIGIT(S)>" pattern, the second (%s... removes everything before and after size attr's " (and " will also be removed).

HTH

Upvotes: 2

Philippe
Philippe

Reputation: 9762

You can use matching groups:

:%s/^.*size="\([0-9]*\)".*$/\1/

This will replace lines that contain size="N" by just N and not touch other lines.

Explanation: this will look for a line that contains some random characters, then somewhere the chain size=", then digits, then ", then some more random characters, then the end of the line. Now what I did is that I wrapped the digits in (escaped) parenthesis. That creates a group. In the second part of the search-and-replace command, I essentially say "I want to replace the whole line with just the contents of that first group" (referred to as \1).

Upvotes: 6

Related Questions