On Mon, September 20, 2010 9:09 pm, Tim Chase wrote:
> Christian gives a workable solution for a certain line-format,
> assuming your search-items are on their own lines, and the
> contents between them are also on their own line(s).
>
> It gets a little trickier when you have them inline:
>
>    aaaacgtaggggggatgca
>           ^^^^^^^^
>
> if you want to extract the information between "acgt" and "tgca"
> (in the above example "agggggga"), you'd have to pull the text in
> visual mode, and use search-offsets
>
>    :nnoremap <f4> /acgt/e+1<cr>v/tgca/s-1<cr>y:new<cr>P
>
> would map <f4> to
>
> /acgt/e+1    " search for 'acgt' and position the cursor
>               " at the end+1 of the match
> <cr>         " execute the search
> v            " go into character-wise visual mode
> /tgca/s-1    " search for 'tgca' and position the cursor
>               " at start-1 (the character before the match)
> <cr>         " execute the search
> y            " yank the resulting text
> :new<cr>     " create a new unnamed buffer
> P            " paste the yanked text in this new buffer
>
>
> You can then save this new buffer as you would any other:
>
>    :w /path/to/wherever/extract.txt

Ok, that can also be done, using some vim scripting, which I prefer,
because it's easier for me to understand:

let startpattern='acgt'
let endpattern='zetgca'
:call writefile([matchstr(getline(search(startpattern)),
\ startpattern.'\zs.\{-\}\ze'.endpattern)], '/path/to/file.txt')

which means (starting from inside to outside):

search(startpattern)                " search for next occurence of
                                      pattern and return the line number.
getline(search(...))                " return the contents of the line,
                                    " that matched
matchstr(getline(...), startpattern.'\zs.\{-\}\ze'.endpattern)
                                    " return the matching part between
                                      the two start and end patterns
[matchstr(...)]                     " Make a list out of the string
                                      returned by matchstr
writefile(..., 'file.txt')          " write the argument 1 (the list)
                                      to the file file.txt

>
> It gets a little trickier if you want to have it mapped *and*
> provide the patterns dynamically, but it can be done:
>
>    :let b:start = "acgt"
>    :let b:end = "tgca"
>    :nnoremap <f4>
> /<c-r>=b:start<cr>/e+1<cr>v/<c-r>=b:end<cr>/s-1<cr>y:new<cr>P
>
> should come fairly close.  That way, you could tweak the values
> for b:start and b:end and <f4> should Do The Right Thing(tm).

And to make it really easier, you can wrap all of it in a function and
make a user defined command, that performs everything for you, so you
don't have to type everything again and again.


regards,
Christian

-- 
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

Reply via email to