41

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?

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

5 Answers 5

58
sed 's/\\n/\
/g'

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

9
  • does this works for all kind of sed's? Jul 4, 2014 at 13:44
  • I believe it should; I tested only on Linux using gnu version.
    – unxnut
    Jul 4, 2014 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. Jul 4, 2014 at 14:13
  • 1
    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'
    – user306023
    Sep 6, 2018 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, 2018 at 23:23
23

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 a historical one and should not be used for new scripts.

8
  • 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, 2014 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 . Jul 5, 2014 at 4:48
  • @terdon how about this echo "aa\nbb" | awk '{gsub(/\\n/,"\n");}1;'? Jul 5, 2014 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, 2014 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. Nov 22, 2015 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.

1

With gnu sed the following also works:

gsed -n -e 'H;${x;s/\\n/\n/g;p;}'
-1

Although I like sed, I think the simplest and most portable solution is using echo:

echo -e "string with\n in it"

Or if you have a file that has strings with "\n"s in it, use command substitution:

echo -e $(filename)

Then add redirection to save to a file as needed.

3
  • 1
    You can hardly get less portable than echo. See Why is printf better than echo?. (you may also want to read When is double-quoting necessary?) Oct 4, 2022 at 16:22
  • This may print the literal string -e string with\n in it depending on the shell and what options are currently set.
    – Kusalananda
    Oct 4, 2022 at 16:53
  • The question is using the sed command which implies that the system is Unix based. I know of no Unix based system which shell doesn't have echo as a built-in or the system has it as a command. I very much understand the purpose of double quotes and single quotes and for my example either will work just fine using the most ubiquitous shell at this time "bash". Yes printf can also be used, but almost every old shell such as bourne shell will have echo. printf may also be built-in to the shell, but not on the older shells, and the printf command may not be supported on older systems as well. Oct 5, 2022 at 17:36

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .