tags:

views:

80

answers:

5

Hi, I'm hand editing CNC Gcode text files and need a way to reference locations in the file and on the toolpath. I want to modify each line in the text file so that it begins with the the upper case N character followed by line numbers which increment in tens for every successive line, then a whitespace,followed by the original text file. Can I do this in vi?

+1  A: 

I'm not sure about vi, but (since you're using the vim tag) Vim allows you to accomplish your task as follows:

  1. Adjust the first line by hand (insert a N10 at the beginning of the line), then put the cursor at the beginning of the next line.

  2. Press qb to start recording a macro (the b names the register used to store the macro; feel free to use a different letter -- and definitely do use a different letter if you've got something useful stashed away in b).

  3. Move the cursor upward to the beginning of the previous line (which you have adjusted by hand). Press v to start visual selection mode, then f to move the cursor to the next space on the line (if you use a single space as your whitespace separator, that is; adjust this step if you're using a tab or multiple spaces).

  4. Press y to yank the selected text. This will also remove the visual selection.

  5. Move the cursor to the beginning of the next line. Press P to insert the previously yanked text before the cursor, that is, on the very beginning of the line.

  6. Move the cursor to the numeric part of the line header. Press 10 C-a (1, 0, control + A) to increment that number by 10.

  7. Move the cursor to the beginning of the next line. Press q to stop recording the macro.

  8. Press 10000000 @b to execute the macro 10000000 times or until it hits the end of the file. This should be enough to take care of all the lines in your file, unless it is really huge, in which case use a bigger number.

...or use Vim to write a simple script to do the job in whichever language you like best, then run it from a terminal (or from withing Vim with something like :!./your-script-name). ;-)

Michał Marczyk
+1, very detailed and helpful! Didn't know about C-a, that's really cool :P
Amir Rachum
A: 

There is two possible ways of doing that without using external tools: macro or Vim-script. The first way is a little cumbersome (and probably not as effective as solution listed below), in my opinion.

The second way could be implemented like this (put the code into your .vimrc or source it other way):

function! NumberLines(format) range
    let lfmt = (empty(a:format) ? 'N%04d' : a:format[0]) . ' %s'
    for lnum in range(a:firstline, a:lastline)
        call setline(lnum, printf(lfmt, lnum, getline(lnum)))
    endfor
endfunction

command! -range=% -nargs=? NumberLines <line1>,<line2>call NumberLines([<f-args>])

NumberLines function enumerates all lines of the file in a given range and prepends to each line its number according to given printf-format (by default, 'N%04d'). To simplify usage of this function I create a new command here that accepts range of lines to process (by default, the whole file) and optional argument—format of the line number.

ib
A: 

Cheating answer:

:%!awk '{print "N" NR "0", $0}'
hobbs
He specifically asked whether this was possible in vi, so this answer is unhelpful IMHO.
Amir Rachum
@Amir Rachum that *is* in vi.
hobbs
@hobbs Isn't this just calling an external command? Anyway, sorry for my misunderstanding, I hope no offense was taken.
Amir Rachum
A: 

The following command will prepend 'N<line number * 10>' to every line.

:g/^/exe 'normal! 0iN' . (line('.')*10) . ' '
too much php
It works much slower than script. For example, in my system it takes 6 second for this command to process 100,000-lines file, while the script I've listed above works in less than 2 seconds (at the same file, of course).
ib
A: 

You can do it easily in Vim with this:

:%s/^/\=line(".")*10 . " "/

This replaces the start of every line with the result of an expression that gives the line number times ten, followed by a space.

I have not timed it, but I suspect it is noticeably faster than the other Vim solutions.

Dave Kirby