How to with (n)vi ...

How do you substitute "abc^Jdef" with "abcdef", where ^J is a \n character?

"%s/abc^Jdef/abcdef/" or "%s/abc^Mdef/abcdef/" does not work. Remember that to type a char literally, one types first ^V.

With emacs this is no problem, there one enters a character literally with ^Q before.

Another question:

"%s/abc/ABC/2" should substitute in every line the second occurrence of "abc" with "ABC".
This is still the behaviour of ed, seems to be half documented in man vi, but does not work.
 
How do you substitute "abc^Jdef" with "abcdef", where ^J is a \n character?

"%s/abc^Jdef/abcdef/" or "%s/abc^Mdef/abcdef/" does not work. Remember that to type a char literally, one types first ^V.

With emacs this is no problem, there one enters a character literally with ^Q before.

Another question:

"%s/abc/ABC/2" should substitute in every line the second occurrence of "abc" with "ABC".
This is still the behaviour of ed, seems to be half documented in man vi, but does not work.
If everything fails, you can invoke sed(1) from within vi:
Code:
:%!sed -e 's/abc\ndef/abcdef/g'
 
...
%s/\(abc\)\@<=abc/ABC/g
...
No, this is incorrect

Edit
Correct (using Perl). Only the second (not the third, fourth, etc) sequence in the line will be changed :
Perl:
open(F_INP,$ARGV[0]);
open(F_OUT,'>',$ARGV[1]);
my @inp=<F_INP>;
close(F_INP);
for my $inp (@inp) {
    if ( $inp =~ m{(.*?)(abc)(.*?)(abc)(.*)} ) {
        my $out=$1.$2.$3.uc($4).$5;
        print F_OUT $out,"\n";
    } else {
        print F_OUT $inp;
    }
}
close(F_OUT);
Run:
perl ./script.pl ./input.txt ./output.txt
 
If everything fails, you can invoke sed(1) from within vi:
Code:
:%!sed -e 's/abc\ndef/abcdef/g'

Unfortunately this does not work.

Use sed (multiline) as normal as a filter:

:%!sed -e 'N;s/abc\ndef/abcdef/g;'

But this one.

I had to run "set shell=/bin/sh", because I run calendar in .tcsh (login shell), and the command put my entries of the
day in the file I am editing.

I think to remember that for doing this, there was a trick with ed. I did not know that sed accepts \n.

It seems that there is no way to avoid external programs when using vi for things that are usual in emacs.
 
It seems that there is no way to avoid external programs when using vi for things that are usual in emacs.
I suppose that because the UNIX way is to favour small filter programs that do one thing only and reduce duplication.
The GNU way is large systems that do lots of things.

The UNIX approach is at the program level, the GNU approach is at the library level.
 
The UNIX approach is at the program level, the GNU approach is at the library level.
Yes, I like the UNIX approach, but in this case a simple thing becomes to complicated.
I think a simple editor should be capable of doing this.

I tried sam that is not line oriented, but selection oriented, till now with no success.
But as plan9 program, one needs more the mouse, scrolling is too primitive.

BTW, the N in sed means that the problem is only solved for two lines? Regexp on two lines only?
 
I think a simple editor should be capable of doing this.
I do tend to disagree, a simple editor should be capable of delegating the task to the correct powerful tool rather than implement a limited "toy" version.
BTW, the N in sed means that the problem is only solved for two lines? Regexp on two lines only?
N (and D) are ways to join the buffers between lines (sed usually operates on lines)


For anything more I would probably use awk instead (a bit more general purpose).
 
Where is vi documented?

Neither man vi nor


Contain detailed information. Where is for example the vi (not ex) command >> documented?

In the man page commands are enumerated, the usage given, but the semantic is unclear, it mentions flags,
do specify them exactly.
Look here: (It's a book, but worth it!)

Learning the VI editor

It's specifically about the classic Vi editor (not Vim etc.) It contains special sections about the various clones, though, including FreeBSD's nvi. Since I read this book, I use vi(1) exclusively for my work! For example: Did you know that Vi also has windows, similar to Vim?
 
And also the ed tutorial that is not in [...]
It is in The Ed Papers. Of course there also is Ed Mastery.

Where is vi documented?
Much in the above references of this thread. I doubt there is one ultimate document that contains
  1. unambiguous definitions of all its syntax and semantics
  2. explains those definitions to mere mortals
  3. functions as a tutorial for the uninitiated and advanced user alike
For #2 and #3 probably covering the most complete vi/nvi/vim and lookalikes landscape is Learning the vi and Vim Editors, currently at its 8th edition. Starting using a vi-variant afresh, and appreciating good online (in program and on the www) help and assistance, vim(1) (vim.org) might be a choice to consider.



How do you substitute "abc^Jdef" with "abcdef", where ^J is a \n character?

"%s/abc^Jdef/abcdef/" or "%s/abc^Mdef/abcdef/" does not work. Remember that to type a char literally, one types first ^V.

With emacs this is no problem, there one enters a character literally with ^Q before.

Another question:

"%s/abc/ABC/2" should substitute in every line the second occurrence of "abc" with "ABC".
This is still the behaviour of ed, seems to be half documented in man vi, but does not work.
Starting with your last question. I'm guessing you're expecting that (n)vi is a strict superset of ed(1) (specifically with respect to "%s/abc/ABC/2"): it is not. vi originated from ex (Ex Reference Manual - Version 1.1 − November, 1977), where Bill Joy used ed as a basis:
Ex is a UNIX text editor, based on and largely compatible with the standard UNIX editor ed.
The functionality of ed(1), (.,.)s/re/replacement/n "where n is a positive number, causes only the nth match to be replaced" is just not present in vi(1), ":%s/abc/ABC/2" does work in vi, but has different semantics. More details later on.

A fine solution with vi working in UNIX collaboration style with sed is:
:%!sed -e 's/abc/ABC/2'
With sed, you can also do :%!sed -e 's/abc/ABC/2g', replacing all matched occurrences (g) starting with the second match etc.; thus skipping just the first matched occurrence. This functionality is not available in ed.

A working solution (of sorts) for your "\n" problem in vi, is also utilising sed as an external filter:
:%!sed -ne '1h;2,$H;$g;$s/abc\ndef/abcdef/gp'
This dumps the complete file in the pattern space (treating it as one line) and then uses it for the substitution; to me that feels like a hack. This also defeats the "stream" aspect of sed as a stream editor.

ed, ex, vi (and variants) and sed are all line-oriented utilities; one more so than the other. I imagine that the historical development context has a lot to do with that. UNIX started its development on a (small) minicomputer (DEC PDP-8) in the sixties; it soon moved to the more workable DEC PDP-11 (still a minicomputer). The PDP-11 was also the basis of ex's initial development by Bill Joy, on a Lear Siegler ADM-3A "glass tube" as video display terminal that had a very constrained keyboard layout. On the other hand, emacs was being developed on a DEC PDP-10: a mainframe computer that was in a completely different category. See for more Bill Joy ed/ex/vi 300 baud development history (mixed with an emacs reference): Understanding the Origins and the Evolution of Vi & Vim

As FreeBSD tends to strive to be POSIX compatible, Open Group - POSIX is also a valuable source of information, and probably for most items that are relevant to FreeBSD where you could find "defining" information about its syntax and semantics, as good as it gets:
Taking the POSIX relevant texts for your "%s/abc/ABC/2"; the substitution command of ed:
Code:
    (.,.)s/RE/replacement/flags
 [...]
The application shall ensure that the value of flags is zero or more of:

count
    Substitute for the countth occurrence only of the RE found on each addressed line.
 [...]
The synopsis of the substitute commmand of ex as used in vi:
Code:
    [2addr] s[ubstitute][/pattern/repl/[options][count][flags]]
Here flags refer to "One or more of the characters '+', '-', '#', 'p', or 'l' (ell)." (see Command Descriptions in ex) that has a different semantics compared to flags of ed.
What might be considered a "total inclusive counting" of all occurrences is the g option:
Code:
If options includes the letter 'g' (global), all non-overlapping instances of the pattern in the line shall be replaced.
However, for count in Command Descriptions in ex:
A positive decimal number. If count is specified, it shall be equivalent to specifying an additional address to the command, unless otherwise specified by the following command descriptions. The additional address shall be equal to the last address specified to the command (either explicitly or by default) plus count-1.

If this would result in an address greater than the last line of the edit buffer, it shall be corrected to equal the last line of the edit buffer.
Which clarifies the different semantics of ex/vi's count compared to ed's count.

:3s/abc/ABC/2 used in vi as an ex command, with (numbered lines) as the following text:
Code:
      1 this is line abc, abc, abc and abc
      2 def this abc line, abc line and still abc line.
      3 this is line abc, abc, abc and abc
      4 def this abc line, abc line and still abc line.
affects lines 3 and 4 where in each only the first occurrence of abc is replaced.


Where is for example the vi (not ex) command >> documented?
More precise semantics of vi's command mode ">>" are given at Shift Right:
Code:
    [count] > motion

If the motion command is the > command repeated:

    If there are less than count -1 lines after the current line in the edit buffer, it shall be an error.

    The text region shall be from the current line, up to and including the next count -1 lines.

Shift any line with characters in the text region specified by the count and motion command 
one shiftwidth (see the ex shiftwidth option) away from the start of the line, as described by 
the ex > command. The unshifted lines shall be copied into the unnamed buffer in line mode.

Current line: If the motion was from the current cursor position toward the end of 
the edit buffer, unchanged. Otherwise, set to the first line in the edit buffer that is 
part of the text region specified by the motion command.
  [...]
 
Its quite fun that once you know where to look, Vi is probably one of the most documented text editors in the world. Perhaps even more so than Visual Studio 6.
 
Much in the above references of this thread. I doubt there is one ultimate document that contains
  1. unambiguous definitions of all its syntax and semantics
  2. explains those definitions to mere mortals
  3. functions as a tutorial for the uninitiated and advanced user alike
Thanks a lot! Your answer may be called: "documentation philology".
 
That

ex 3s/abc/ABC/2 = ed 3;+1s/abc/ABC/2

seems to follow a general rule. We also have:

ex 2p5 = ed 2;+4p
ex 1d3 = ed 1;+2d

In 5.1 of 4.4BSD "Ex Reference Manual" we read, as also cited for posix by Erichans:
A number of commands also may take a trailing count specifying the number of lines to be involved in the command.† Thus the command ‘‘10p’’ will print the tenth line in the buffer while ‘‘delete 5’’ will delete five lines from the buffer, starting with the current line.
 
Looks like Garry Geigex was wrestling with editors when he by chance wrote the first D&D manual...
 
Pick up one of the vi/ex reference cards where their command are succinctly described.
Thanks. I think, I am writing my own reference card as I read the documentation, but I can use your links to compare.

I use vi since many years, for example for editing configuration files, but now I decided to go into more details.

I think, I will continue using mainly emacs, but better knowledge of ex/vi do not damage.

Vi is rich on movement commands, sure emacs has similar ones, but I do not use them. The reason for using emacs
are subtilities like the substitution command in my first posting here, and of course, the weight of using it for decades.

I think, the right editor would be neither vi nor emacs, perhaps sam, perhaps teco, perhaps something not jet written.
 
Back
Top