简体   繁体   中英

vim regex : multi-line edit and controlling the cursor position

A text file is formatted like this:

Section 4 Area B Unit 20
   stuff i don't need...
   stuff i don't need...
   45990 - Title of Project that I want to save
   line of text I need to keep
   line of text I need to keep
   2010-11 this line (starting with 2010) is not needed
   stuff i don't need

Section 589 Area C Unit 1005
   stuff i don't need...
   stuff i don't need...
   45990 - Title of Project that I want to save
   line of text I need to keep
   line of text I need to keep
   2010-11 this line (starting with 2010) is not needed
   stuff i don't need

and these sections repeat by the hundreds. The "stuff i don't need" lines are actually about 30 or so. I need to keep the association of the "Section..." line, "Title..." line and "line of text I need to keep" related to each other. So I was hoping to first destruct the text document down (linewise) to the stuff I need before operating on it further (character-wise). So I wrote this:

g!/\Section\s\d*\sArea\s\h\sUnit\s\d*\n\|^\s\{3}\zs\d*\s-\_.*\ze2010-11/d

After deleting I get the "Section.." line and the "Title..." line, but never the subsequent lines underneath the "Title.." line. Those subsequent lines vary from 4 to 8 lines, but the "2010-11" line is consistent and always what I no longer want.

You can see I tried using zs and ze to select what I do not want deleted. I think the selection is working because if I change the command to "2011-12" then there is no match and the (OR) half of the command does not return a result.

I think the fault might be the cursor position(?), but I'm not sure and my effort to fix that has failed.

Can anyone see my error?

Thanks!

:g finds every line matching start of the pattern, ! will revert the selection and command will get applied to these lines.

Would something like g/^Section.../normal! j2dd3jd} g/^Section.../normal! j2dd3jd} do?

If not you can use a search for the Title line inside normal! You may need to enclose it in "exec" but may be much simpler to write a function.

Do you really need to use vim? Seems like job for Perl to me.

There are many ways to do t, I'm sure. I think this sequence of commands should work (ignoring comment lines that begin with double quote):

" global delete of line below 'Section' to line before 'Title'
g/^\s*Section/+1;/Title/-1delete
" global delete from date line to line before 'Section'
g/^\s*\d\d\d\d-\d\d/;/^\s*Section/-1delete
" go to top line of buffer
gg
" delete last chunk, from final date to last line
/^\s*\d\d\d\d-\d\d/;$delete 

Give this a whirl.

:silent! g/^Section/+ , /^\s\+\d\+ -/- d
:g/^\s\+2010/ , -/\nSection\|\%$/ d

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM