5

For example in the vi editor a file is created with 8 lines of the word today and I was wondering how I would change 4 lines to the word yesterday with once command.

3 Answers3

9

Most ex commands (i.e. commands invoked by pressing : (colon) then the command name) that act on the content of the file allow a range to be specified before the command. This range specifies which lines are affected by the command. The general form of a range is two numbers separated by a comma, and the command acts on all the lines from the first number to the second number inclusive. For example

1,4s/today/yesterday/g

replaces all occurrences of today by yesterday in the first four lines of the file.

You can put a sign before a number to make it relative to the current line. For example

-1,+1s/today/yesterday/g

performs the replacement on the previous line, the current line and the following line. If you include the comma but leave out one of the numbers, that means the current line, for example

,+1s/today/yesterday/g

performs the replacement on the current line and the following line. You can also use $ instead of a number to mean the last line of the file. If you leave out the comma and specify only one number, then the command acts on this line only, e.g.

+1s/today/yesterday/g

performs the replacement only on the following line.

  • 1
    Gilles, you're an emacs guy, stop answering vi questions :) . This is a great answer nevertheless. The only thing I'd add is that vi is not capable of $,-1s/// i.e. going backward from the end of the file. – grochmal Oct 23 '16 at 03:19
  • @grochmal I suppose the easiest way to achieve that would be to move the cursor to EOF then :-1,s/today/yesterday/g – Darren H Oct 23 '16 at 07:49
1

You can use the command:

:n,m s/today/yesterday/

i.e. replace the word 'today' with 'yesterday' from line n to m.

andreatsh
  • 2,025
  • You can also do this over a visual or visual block selection, or use %s for the entire buffer. And you probably want /g at the end to replace more than one entry per line. – Xiong Chiamiov Oct 22 '16 at 22:30
  • 2
    @XiongChiamiov Only in vim, not in plain vi. – Gilles 'SO- stop being evil' Oct 22 '16 at 22:31
  • @XiongChiamiov While you can do it over any kind of visual selection, it always acts as a range of lines, and will affect it even if the affected text is partially or wholly outside the selected region. There's no purpose to not using visual line mode. – Random832 Oct 23 '16 at 06:54
  • @Random832 Yes, I mistyped - I meant visual line when I said visual block. Reading over it now I can see how you thought I was suggesting limiting only part of the line, but really I was trying to just say that you can use a visual selection rather than having to type out line numbers. – Xiong Chiamiov Oct 24 '16 at 17:59
0

Try this :

Go to the command mode in vi editor and try the below command:

:%s/today/yesterday/g

g - replace today with yesterday globally.