sed only removing \n provided by sed '=' command

Your second sed script,

N
s/\n/ /

does not work the way you expect because it will read one line, then append the next line to it with an embedded newline inserted by the N command, and then replace that newline with a space (and output). When reading the line after, this result from the first two lines is discarded.

Instead, you would have had to use the hold space:

H;            # append to hold space with a '\n' embedded
              # for the last line:
${
    x;        # swap in the hold space
    s/\n//;   # delete the first newline (from the H command on the very first line of input)
    y/\n/ /;  # replace all other newlines with spaces
    p;        # print result
}

This script is running once for each line of input, collecting data in the hold space until we hit the last line. At the last line, we process the collected data and output it.

You would run this with sed -n:

$ sed '=' <file2 | sed -n 'H; ${ x; s/\n//; y/\n/ /; p; }'
1 this is  2  not is  3  is is  4  this biz

(no newline at end of output, as there was none at the end of the input).

Alternatively, with an explicit loop we may use N. The trick here is to never reach the end of the script until we're ready to print the result.

:top;     # define label 'top'
N;        # append next line with a '\n' embedded
$!btop;   # if not at end, branch to 'top'
y/\n/ /;  # replace all newlines with spaces
          # (implicit print)

This script only runs (to the end) once and manages the reading of the data itself whereas the previous script was fed data by the built-in read loop in sed (which replaces the pattern space for each line read, which was your issue). It uses the pattern space rather than the hold space to collect the data and processes it when the last line has been read.

On the command line:

$ sed '=' <file2 | sed ':top; N; $!btop; y/\n/ /'

(same output as above)


If GNU sed, try this

$ sed -z 's/\n/ /g' file2
this is   not is   is is   this biz
$

tr does an equally good job.

$ tr '\n' ' ' <file2
this is   not is   is is   this biz
$

This is fundamentally because sed is line oriented. What happens is

  • sed loads the first line 1 into pattern space
  • the N command loads the next line, and appends it to pattern space, separated by \n, giving 1\nthis is
  • we replace \n by space giving 1 this is

and we're done; the pattern space is printed and then the steps are repeated for each of the remaining (pairs of) lines.