Sed in vi - \r and \n not giving desired results

I use many different machines at work, each with different versions of o/s's and installed applications. Sed in vi is particularly inconvenient in the sense that sometimes it will accept the "\r" as a carriage return, sometimes not. Same thing with "\n". For instance, if I have a list of hosts that are all on one line separated by a space then I need them in line-by-line format. On some machines I can do this in vi:

:%s/ /\r/g

or

:%s/ /\n/g

I don't know if the editor will accept \r or \n until I try. On some machines it will treat either as a regular character by inserting an "r" or "n" in place of the spaces. Is this relative to my version of vi, o/s, sed, or all? I'm assuming \r and \n are ASCII characters. Is there a chance the ASCII chars are defined differently depending on the o/s? (I thought it was a standard) How can I determine in advance which host will accept \r or \n as carriage return and newline, respectively, before I start vi?

I do not have the authorisation to upgrade the o/s or editors to the latest versions.

I generally use either \ or cntrl-v or \ + cntrl-v in front of enter for cr or nl in vi, aka 'visual ex', in ':' mode, which is raw 'ex', which is extended 'ed'.

BTW, sed, the stream editor, likes \n in regex (from field of substitute s) and \ + linefeed in substitute s to field, treats cr as a literal.

The other versions of vi (ex) and sed may honor \r and \n in other contexts, but as you note, it is spotty.

You can install in your own home dir a GNU version of vi and sed, and put it up-PATH to have a consistent home world. If on another ID, having your personal tools in a directory is handy, as you can add the dir up-PATH while you are there to get to your tools. You have to write scripts that do not assume your ID. You can share the tools to others easily, too. You just have to use the old tool where you cannot get to your version and in prod scripts.

On some old versions of sed the only way to get a newline is to stick a literal newline in the string, ugh.

Beauty is in the eye of the beholder. I like my lines to stay lines, so I never looked for a replacement for '\
'. Often, in C/C++, I put strings in one line per, like:

        fputs(
"\n"
"Usage: snark [ file_name . . . ]\n"
"\n"
"Encodes each file with sarcasm, producing an output file: <file_name>.nyuk\n"
"Cannot be used in Nyack.\n"
"\n",
            stderr );

sed can't match newlines anyway, he must be adding newlines.

sed matches newlines, which sed puts in the buffer with s or N:

$ echo 'x
y' | sed '
  N
  /\n/p
  s/.*/line1\
line2/
  /\n/p
  s/\n/&&&&/
  p
  s/\n/\\n/g
 '
x
y
line1
line2
line1
 
 
 
line2
line1\n\n\n\nline2

.* is not a newline, you're matching everything but the newline, which doesn't get stored when sed reads a line from stdin.

Of course, .* is not a newline, unless that is all that is in the buffer.

\n is a newline in the regex

'\
' is a newline in the s result

N embeds a newline before the next line in the buffer. My example was:

  1. N puts a second line in the buffer, and as the buffer contains \n, it is printed.
  2. .* matches newline and all else when I replace the buffer with two constant lines using the '\' + newline.
  3. That prints too, as it also matches /\n/.
  4. You can pick up just the newline and lay it down 4 times using &.