Using the caret symbol (^) in substitutions in the vi editor

In the vi editor, as well as in both ex and ed (as found on BSD systems), the ^ addresses the previous line. This means that the command ^d would delete the previous line, ^m. would swap this line with the previous, and that ^,.s/old/new/g would substitute all strings matching old with new on the previous line and on this line.

The vim editor, being an extended re-implementation of the original vi and ex editors, commonly installed on Linux systems under the names vim, vi, and ex, does not have this way of addressing the previous line, and will respond with "E492: Not an editing command" if you try to use it. You may use - or -1 in its place:

-,.s/old/new/g

Using - or -1 in place of ^ also works in ed, ex and in vi on non-GNU systems.

The POSIX standard says the following about this in relation to the ed editor:

Historically, ed accepted the ^ character as an address, in which case it was identical to the <hyphen-minus> character. POSIX.1-2017 does not require or prohibit this behavior.

There is a similar wording for the vi and ex editors (ex is vi "in line editor mode"):

Historically, ex and vi accepted the ^ character as both an address and as a flag offset for commands. In both cases it was identical to the - character. POSIX.1-2017 does not require or prohibit this behavior.

Note that the text that you seem to be quoting says that ^,. addresses all lines from the top of the file to the current line. This is not correct. It only addresses the previous and the current line, and only does so in "historically accurate" implementations of vi (and ex and ed). To address all lines from the start of the editing buffer to the current line, use 1,..

Just to provide another piece of trivia: The ^ address can also not be used in the GNU implementation of the ed editor. As in any other implementation of ed, - or -1 may still be used as an alternative.


The site where you found this vicommand is wrong.

It might be that 1996 site or one of the many other who copied/pasted these lines without double checking.

Using vi, the Unix Visual Editor

…

:.,$s/old/new/g   Substitutes old with new from the current
                       cursor position to the end of the file

:^,.s/old/new/g   Substitutes old with new from the beginning
                       of the file to the current cursor position

© Copyright 1996 University of Washington Computing & Communications.

What should have been written is:

:1,.s/old/new/g

The caret has several usages under vi. One of them is to tell the beginning of line in the pattern area, so /^old/means "old" when starting line just like $ means end of line so /old$/ means "old" when ending a line.

I'm sure the confusion is due to this symmetry. The author (Rick Ells) thought the caret ^ means either beginning of a file or beginning of a line just like $ means end of a file or end of a line but the fact is it is not the case.

It also happens the caret also has a specific and different meaning when used as an address like Kusalananda pointed but IMHO it is anecdotal as I have never met anyone using this shortcut, -1 being much more intuitive.

Tags:

Vi

Editors