17

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.
  • 195
  • 1
  • 1
  • 7
  • @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
  • Does this answer your question? [How can I replace each newline (\n) with a space using sed?](https://stackoverflow.com/questions/1251999/how-can-i-replace-each-newline-n-with-a-space-using-sed) – icc97 Sep 21 '22 at 08:40
  • Anyone have any luck using the multi-line flag for sed's substitute? I was trying to use `s/.../.../m` – Yzmir Ramirez Dec 24 '22 at 16:33

8 Answers8

14

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> 

From sed --help

  -z, --null-data
                 separate lines by NUL characters

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

icc97
  • 11,395
  • 8
  • 76
  • 90
StefanKaerst
  • 331
  • 2
  • 6
  • Took me a while to understand this answer, because **the main point here is the `-z` parameter**. You can try replacing the newline character with something else via `sed "s/\n/xxx/g"` - but that won't work. First you get sed to ignore the `\n` characters (but still leave them in the output) and *then* you can get sed to blindly do what it generally refuses to do and remove the `\n` whilst sed is hunting around for `NUL` – icc97 Sep 21 '22 at 08:29
13

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,676
  • 2
  • 24
  • 37
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
  • 50,406
  • 14
  • 85
  • 110
  • 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
2
{ echo foo; echo bar; } | awk '{printf("%s ", $0)}' 
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • 4
    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
  • This is a perfectly good answer, and was useful for me. Even though it doesn't exactly answer the question it does work and is the next best thing. Up votes only require that the answer is 'useful' not that it answers the question exactly as stated. – icc97 Sep 21 '22 at 08:24
  • I second icc97, useful answer for me to strip a json file of linebreaks (which sounds easier than it is, I think) – Heiko Jakubzik May 16 '23 at 18:49
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'

  • Please use some code formatting, or your example becomes impossible to read :-) Also, this is pretty much the same as other answers. – Gwyneth Llewelyn Jun 14 '23 at 17:12
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

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
  • 466
  • 4
  • 11
-1

you can also try :

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