Search code examples
regexvimscriptingvim-macros

How would you make this into a VIM macro?


So one of the common tasks that I do as a programmer is debugging a live system. And one of the ways that I debug a live system is to capture a verbose log from the console.

Typically the log file has around 20 extra lines for every one line I am interested.

To minimize my macro script I went about creating a macro that will grab ONLY the one line out of 20 that I am interested in! (As opposed to doing 20 substitutions for all the lines I didn't want... which would make the macro 20 times longer than it needs to be.) The rest of this macro code will turn that one line into a *.csv file so I can play with the numbers in Matlab or Excel as I see fit.

Here is the code for the macro (these commands are Ultra Edit specific commands):

Clipboard 1
ClearClipboard
Loop 
Find RegExp "{*}DBGLINE: STR1 ( * ) STR2 ( * )^p"
IfFound
CopyAppend 
Else
ExitLoop
EndIf
EndLoop
SelectAll
Delete
Paste 
Find RegExp "{*}DBGLINE: STR1( "
Replace All ""
Find RegExp " ) STR2 ( "
Replace All " , "
Find RegExp " )*^p"
Replace All "^p"
ClearClipboard

*FYI, I have posted the API/description of what each command does online.

Let me break down in a more human readable pseudo code what this macro is doing:

buffer = "";
// Keep finding $REGEX until EOF
while(1) {
    if( Find $REGEX ) {
        Select the text;
    } else {
        break;
    }
    buffer += selected piece of text;
}

// Now we can focus only on the selected lines from the log file
Select the entire text in the file;
Delete all selected text;
Paste the buffer into the text file;

// Convert the human readable text into a *.csv file
Parse out all the non-numerical content;
Replace with " , " commas;

I know how to create simple macros in VIM by adding a map to my .vimrc file:

map $KEYBOARD :%s/$STR_A/$STR_B/gc<CR>

But I was wondering if there was some way to do the while(1) and the CopyAppend in a macro. Like in some sort of .vimrc defined function:

function! CustomScript1()
...
" TODO: vim commands here
...
endfunction

map $KEYBOARD :call CustomScrip1()<CR>

So how would you change the above UltraEdit macro into a VIM function?

I really need to get the ability to recreate this kind of script in VIM because I am currently stuck doing 20 substitute (sometimes more) and replaces... and it is driving me nuts wasting my time doing such inelegant solution to parsing the log file!


Solution

  • If you are interested in all of the occurrences of your pattern, try using :v to delete all of the other lines:

    :v/pattern/d_
    

    If you are only interested in the first one, try either / or search(). In a function, it would look like this:

    function! CustomScript1()
       " search where your pattern is
       let l = search(pattern) " move to the line found -- i.e., no 'n' flag
       " get rid of everything else
       if l > 0
          if l>1
              :0,-d_
          endif
          if l != line('$')
              :+,$d_
          endif
       endif
       " format as CSV
       :s/\D\+/ , /g
    endfunction