tags:

views:

140

answers:

4

Hi, does anyone know if it is possible to concatenate matches resulting from a search into a single register? E.g, I have a file with following contents:

aaa :xxx 123
bb :y 8
ccccc :zzzzz 1923

Now what I want is to copy column starting with ':' somewhere else. Unfortunatelly I can't use visual block mode, because the first column hasn't fixed width. I thought that I could search for the second column (:\w+) and store the maches into a register.

A: 

I would first start with parsing the file. For this use TextFieldReader rather than inventing your own CSV parser:

using Microsoft.VisualBasic.FileIO;

TextFieldParser reader = new TextFieldReader("C:\MyFile.txt");
reader.Delimiters = new string[] { " " };
string[] currentRow = null;
while (!reader.EndOfData)
{
    try
    {
        currentRow = reader.ReadFields();
        foreach(string field in currentRow)
        {
            //save this field...
        }
    }
    catch (MalformedLineException ex)
    {
        //handle exception the way you want
    }
}

Once I have the data I would extract just the column that I am interested in. If you can assume that each line has the same pattern then you can figure out the right column during parsing the first row and then while parsing the rest of the rows you can just save the appropriate column. You don't have to save the whole file into the memory.

EDIT: I am terribly sorry, I thought the question was about C# programming. My mistake - sorry.

David Pokluda
World doesn't end at Micro$oft technologies ;-) ;-) ;-)
kyku
-1 for wrong answer. edit or remove.
Mykola Golubyev
+1  A: 

You could make a macro:

qa (make a macro and store it in register a).

"Rye (yank to end of word and append it to register r - capital means append, lowercase overwrite.)

n (next match)

q (end recording)

If there are 10 matches, do 10@a Make sure register r is empty when you begin.

Michiel de Mare
forgot to add /:\w+ at the algorithm begin.
Mykola Golubyev
+1  A: 

Add this to your .vimrc or create any file in the vim plugin folder with the following content.
After you execute this lines through .vimrc or plugin, use :CopyTextAfterColon command and then simply insert from the system buffer text you need.

  function! s:copy_after_colon()
    let values = ''

    let pattern = '^.*:\(\w\+\).*$'

    for line_number in range(1, line('$'))
        let line = getline(line_number)
        if line =~ pattern
            let value = substitute(line, pattern, '\1', '')
            let values .= value."\n"
        endif
    endfor

    let @* = values
endfunction

command! -nargs=0 CopyTextAfterColon call <SID>copy_after_colon()

You can adapt this later for different purposes.

Mykola Golubyev
+6  A: 

Another way:

:g/:/norm f:"Aye

Per :h quote_alpha, if you use an uppercase register name, it appends rather than replaces the contents of the register. If you run this and check the contents of register "a, you'll see

:xxx:y:zzzzz

(Possibly with linebreaks, depending on how you have cpoptions set.)

Brian Carper
Really pretty one.
Mykola Golubyev