8

I tried to remove all newlines in a pipe like this:

(echo foo; echo bar) | sed -e :a -e N -e '$!ba' -e 's/\n/ /g' | hexdump -C

Which results on debian squeeze in:

00000000  66 6f 6f 20 62 61 72 0a                           |foo bar.|
00000008

Not removing the trailing newline.

tr -d '\n' as in How do I remove newlines from a text file? works just fine but isn't sed.

Community
  • 1
  • 1
j.l.
  • 105
  • 1
  • 1
  • 6
  • @zsolt the difference between questions is only that for the other it may be acceptable to leave the trailing newline. – j.l. Jul 13 '11 at 17:44

8 Answers8

11

Sorry can't be done using sed, please see: http://sed.sourceforge.net/sedfaq5.html#s5.10 and a discussion here: http://objectmix.com/awk/26812-sed-remove-last-new-line-2.html

Looks like sed will add back the \n if it is present as the last character.

Kevin Burton
  • 11,178
  • 2
  • 21
  • 35
  • Thanks and sorry for not reading the FAQ before asking. This solves my problem perfectly fine. Maybe I should've really asked: "Can I remove all newlines (\n) using only sed, invoked once in a pipe? - If so how?" – j.l. Jul 13 '11 at 17:48
7

you need to replace \n with something else, instead of removing it. and because lines are seperated by \n (at least on GNU/Linux) you need to tell sed to look for some other EOL character using -z, like so:

> echo -e "remove\nnew\nline\ncharacter" | sed -z "s/\n//g"
removenewlinecharacter> 

sed would normally remove entire lines (using /d), like so:

> echo -e "remove\nnew\nline\ncharacter" | sed "/rem\|char/d"
new
line
> echo -e "remove\nnew\nline\ncharacter" | sed -r "/rem|char/d"
new
line
>

using /d every line containing an EOL would be deleted, which are all lines. (one)

> echo -e "remove\nnew\nline\ncharacter" | sed -z "/\n/d"
> 

HTH

StefanKaerst
  • 151
  • 1
  • 4
3

If you want to remove the last \n you need an external utility, or use e.g. awk.

printf "%s" `(echo foo; echo bar) | sed -e :a -e N -e '$!ba' -e 's/\n/ /g'`

should work.

Zsolt Botykai
  • 48,485
  • 14
  • 85
  • 106
  • although in this example it's no problem I prefer always the variant with double quotes around the arg. – j.l. Jul 15 '11 at 13:07
0

Compare: (echo foo; echo bar) | sed -e :a -e N -e '$!ba' -e 's/\n/ /g' | hexdump -C with (echo foo; echo bar) |tr -d '\n' | hexdump -C and then with echo foo; echo bar) | hexdump -C | sed -e :a -e N -e '$!ba' -e 's/\n/ /g'

0

If foo and bar are not expected to contain new lines, then you must beware that

(echo foo; echo bar)

will add a new line after each echo

(echo -n foo; echo -n bar)

will not add a new line at the end of the output. So it may be that you don't need sed to remove new lines at all even if it did remove the trailing lines.

Tim
  • 1
0
{ echo foo; echo bar; } | awk '{printf("%s ", $0)}' 
glenn jackman
  • 223,850
  • 36
  • 205
  • 328
  • 3
    No, the OP himself introduced a way to do it with `tr` and explained, that that's not a `sed`-solution. It is obvious, that he isn't interested in an `awk`-reply. – user unknown Jul 13 '11 at 16:49
0

The answer of Stefan Kaerst is perfect:

(echo foo; echo bar) | sed -z "s/\n//g" 

This will export "foobar", as the parameter -z, --null-data separates end of lines by NUL characters (even thought there are no nulls in the text: foobar="66 6f 6f 62 61 72").

An useful example

I use this command to restore paragraphs with broken lines:

cat novel.txt | sed -r 's/^(.{53,80})$/\1<br>/;' | sed -z "s/<br>\n//g" 

This joints long lines if they are longer then 53 characters.

A) Find lines longer then 53 characters and add '<br>' at their end.

B) Find '<br>' with newline and remove it.

Thank you, Mr. Kaerst!

xerostomus
  • 366
  • 2
  • 9
-1

you can also try :

(echo foo; echo bar) | sed 's/\n//' | xargs echo -n
Amith
  • 6,563
  • 6
  • 32
  • 45
GOTROK
  • 1