20

I'm so confused with GNU sed, POSIX sed, and BSD sed's myriad of options. How do I replace literal \n with the newline character using these three sed types?

  • They have many different things, what part do you want to know? – cuonglm Jul 4 '14 at 13:25
  • @Gnouc i think now it's clear. – Avinash Raj Jul 4 '14 at 13:27
  • 1
    Did you have a look at this question ? – groxxda Jul 4 '14 at 13:29
  • 2
    What do you want to happen on input like foo\\nbar or foo\\\nbar? – Gilles Jul 5 '14 at 10:44
  • simple, foo\\ in the next line it would be bar. – Avinash Raj Jul 5 '14 at 10:47
25
sed 's/\\n/\
/g'

Notice the backslash just before hitting return in the replacement string.

  • does this works for all kind of sed's? – Avinash Raj Jul 4 '14 at 13:44
  • I believe it should; I tested only on Linux using gnu version. – unxnut Jul 4 '14 at 14:07
  • 11
    @AvinashRaj. That's POSIX and worked with the original sed command in Unix v7 in 1979. The only place where that might not work would be non-POSIX stripped-down implementations of sed like some stripped-down busybox-based ones. That won't work in csh but it's a csh issue. – Stéphane Chazelas Jul 4 '14 at 14:13
  • Since \\n is used in the search portion, why not use \n in the replace ? the former seems to imply the latter exists. ie. why not this $ echo '1\n2'|sed 's/\\n/\n/g' – Marcus Linsner Sep 6 '18 at 19:24
  • In this case, \n is a literal, implying that it appears as the two characters: abackslash followed by n, and not as a single newline character. Hence,two backslashes for making backslash a literal and then n – unxnut Sep 6 '18 at 23:23
8

Since you already have your portable sed answer, I'll just mention that sed is rarely the best tool if you need to somehow manipulate newlines. Perl is very nearly as portable as sed, is installed by default on most *nix systems and can deal with this very easily:

printf '%s\n' 'aa\nbb' | perl -pe 's/\\n/\n/g'

Another very portable choice is awk:

printf '%s\n' 'aa\nbb' | awk  '{gsub("\\\\n","\n")};1'

On Solaris, remember to use the standard awk in /usr/xpg4/bin, the one in /bin is an historical one and should not be used for new scripts.

  • I'd say awk has similar portability issues (Is my awk plain old awk, nawk or gawk?). Actually, the version in my Solaris boxes lacks gsub(). My vote here is for Perl (perl -nlawe '...' approximates the automatic behaviour of awk). – arielCo Jul 4 '14 at 22:07
  • 2
    @arielCo: For awk portability, stick with a version of awk that is POSIX compliant and only use those features and you should be fine. On Solaris you will find one as /usr/xpg4/bin/awk . – Scrutinizer Jul 5 '14 at 4:48
  • @terdon how about this echo "aa\nbb" | awk '{gsub(/\\n/,"\n");}1;'? – Avinash Raj Jul 5 '14 at 12:05
  • @arielCo actually, awk is more portable than perl. My second awk approach which does not use gsub() should work just about everywhere. Even busybox has an awk. – terdon Jul 5 '14 at 12:07
  • 1
    gsub() is POSIX (gsub, was added in SVR3.1, POSIX awk is based on SVR4 with a few additions see the gawk manual for more information), gensub() is the GNU extension. The original awk still found as /bin/awk on Solaris, did not support support gsub(), but didn't not support a multi-character FS either. – Stéphane Chazelas Nov 22 '15 at 12:34
1

If Holdspace is empty you can also do:

sed '/\\n/G;s/\\n\(.*\)\(.\)/\2\1/;P;D'

...but uxnut's answer is already both faster and more simple, so you can take it as you will.

Another extraneous possibility:

INPUT | sed -n l | while read v ; do printf "${v%?}" ; done

But beware, ^that translates all standard C-style \backslash escapes - like \backspace and \return and \00octals and whathaveyou.

0

With gnu sed the following also works:

gsed -n -e 'H;${x;s/\\n/\n/g;p;}'
New contributor
Dirk Hoffmann is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
-2

You require a solution in sed, and that is already given below. But I wanted to add another possibility that IMHO is just easier and faster,

tr -d "\n"
  • 1
    what does this do? delete all newlines from input? – mikeserv Aug 5 '14 at 21:51
  • Yes, that is exactly what it does – jpmuc Aug 6 '14 at 6:04
  • 5
    but... why? what does that have to do with the question at all? – mikeserv Aug 6 '14 at 6:44
  • 1
    This just removes "\n" when the question is asking how to replace the string "\n" with actual newlines. – spuder Nov 10 '17 at 21:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.