Why SED can't see the last newline character?

Removed.
My question does not make sense. and SED does see the last newline character.

But I still have a question:
How to remove the last newline character(the newline character at the end of last line) using SED?

---------- Post updated 05-01-11 at 10:51 AM ---------- Previous update was 04-30-11 at 11:14 PM ----------

I just realized SED is unable to do what I desired, because SED is line oriented, SED removes the newline character when it reads a line into the Pattern Space and adds a newline character when it outputs the data from the Pattern Space, so all the SED commands can't operate on that newline character at all(You may argue the N command can do that, well it can't for the last newline character).

If you have a multiline file and you really must remove the last newline, try something like:

last=$(tail -1 old)
sed '$d' < old > new
echo -n "$last" >> new
#or
echo "${last}"\\c  >> new
#depending on your style of echo

This is odd requirement though. :confused:

Thank you, Perderabo
I knew how to remove the last newline character with AWK, or the code you provided.

I was wondering if this could be achieved with a SED one liner, and later I realized that it's not possible.

For the odd requirement, it is because the last newline may cause problems when it appears in a WML file, which might not be displayed correctly in some old mobile devices when opened with a browser.

In default operation, sed cyclically copies a line of input, 
less its terminating newline character, into a pattern space (unless there is something left after a D command), 
applies in sequence all commands whose addresses select that pattern space, 
and at the end of the script copies the pattern space to standard output (except when -n is specified) and 
deletes the pattern space. Whenever the pattern space is written to standard output or a named file, 
sed will immediately follow it with a newline character

remove last newline you can use

sed 'N;$s/\n//' file

or

sed '{$H;x;s/\(.*\)\n\(.*\)/\1\2/;1d}' file

regards
ygemici

They don't work. as you cited the text, sed always appends a newline when it outputs a line of text, so I think there's no way of getting rid of the last newline character in sed.

What is not working? If you N command then sed append next line to pattern space. Next line is separated from the original pattern space by a newline character..If you H command appends the contents of pattern space to the contents of the holding space.And these are separated by a newline.

That newline you mentioned is not the last newline, the last newline is added automatically by sed when it outputs the line, you don't have control over this last newline.

kevin@kevin-laptop:~ $ cat data
aaa
bbb
ccc
ddd
eeee

kevin@kevin-laptop:~ $ sed 'N;$s/\n//' data | xxd
0000000: 6161 610a 6262 620a 6363 630a 6464 640a  aaa.bbb.ccc.ddd.
0000010: 6565 6565 0a                             eeee.

kevin@kevin-laptop:~ $ sed '{$H;x;s/\(.*\)\n\(.*\)/\1\2/;1d}' data | xxd
0000000: 6161 610a 6262 620a 6363 630a 6464 6465  aaa.bbb.ccc.ddde
0000010: 6565 650a                                eee.

As you can see from the output of the scripts you provided, the newline character(0a) is there.

Hmm ok I understand that you meant..
If the last line of the your a newline , as for I know (gnu) sed will add that newline to the output but delete all others..For this you can use tr command.

$ for i in $(sed "" file); do [ "$i" == "`sed -n " $(sed -n '$=' file) p" file`" ] && echo "$i"|tr -d '\n' || echo "$i"; done
aaa
bbb
ccc
ddd
eeee $

or

if it s has problem because of IFS

$ while read -r i ; do [ "$i" == "`sed -n " $(sed -n '$=' file) p" file`" ] && echo $i|tr -d '\n' || echo $i; done <file
aaa
bbb
ccc
ddd
eeee $

or

$ ax=$(sed ':a;$!N;$!s/\n/'\\\\n'/;ta;s/[\n]$//' file) && printf "$ax"
aaa
bbb
ccc
ddd
eeee $

regards
ygemici