7

How to insert newline character after comma in ),( with sed?

$ more temp.txt
(foo),(bar)
(foobar),(foofoobar)

$ sed 's/),(/),\n(/g' temp.txt 
(foo),n(bar)
(foobar),n(foofoobar)

Why this doesn't work?

qazwsx
  • 25,536
  • 30
  • 72
  • 106

4 Answers4

7

sed does not support the \n escape sequence in its substitution command, however, it does support a real newline character if you escape it (because sed commands should only use a single line, and the escape is here to tell sed that you really want a newline character):

$ sed 's/),(/),\\
(/g' temp.txt
(foo),
(bar)
(foobar),
(foofoobar)

You can also use a shell variable to store the newline character.

$ NL='
'
$ sed "s/),(/,\\$NL(/g" temp.txt
(foo),
(bar)
(foobar),
(foofoobar)

Tested on Mac OS X Lion, using bash as shell.

Sylvain Defresne
  • 42,429
  • 12
  • 75
  • 85
  • In the first approach, why it needs to be `\\` but not `\`? – qazwsx Feb 27 '12 at 22:41
  • The command you pass to `sed` are not supposed to contains newline. So if you want to pass a newline, you need to escape it with a backslash so that `sed` know you did on purpose. And you need a second backslash to protect the first from being interpreted by the shell (using backslash to escape character in regexp was IMHO a bad idea since it is also generally used to quote character in string, and thus you usually have to use double backslash in regexp). – Sylvain Defresne Feb 28 '12 at 09:29
3

This works for me:

$ echo "(foo),(bar)" | sed s/')','('/')',\\n'('/g
(foo),
(bar)

I am using:

  • GNU sed 4.2.2
  • GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
Jeff Learman
  • 2,914
  • 1
  • 22
  • 31
jeyrey
  • 31
  • 2
3

OK, I know this question is old but I just had to wade trough this to make sed accept a \n character. I found a solution that works in bash and I am noting it here for others who run into the same problem.

To restate the problem: Get sed to accept the backslash escaped newline (or other backslash escaped characters for that matter).

The workaround in bash is to use:

$'\n'

In bash a $'\n' string is replaced with a real newline.

The only other thing you need to do is double escape the \n as you have to escape the slash itself.

To put it all together:

sed $'s/),(/),\\\n(/g' temp.txt
(foo),
(bar)
(foobar),
(foofoobar)

If you want it actually changed instead of being printed out use the -i

sed -i $'s/),(/),\\\n(/g' temp.txt
Dom
  • 2,240
  • 16
  • 22
3

You just have to escape with a backslash character and press the enter key while typing:

$ sed 's/),(/),\
(/g' temp.txt
(foo),
(bar)
(foobar),
(foofoobar)
jcollado
  • 39,419
  • 8
  • 102
  • 133
  • This doesn't work if you put the sed command in a bash file. Only if you put `\\` before the new line character, it starts to work. But I wonder why? – qazwsx Feb 27 '12 at 22:42
  • @user001 For what is worth, the exact same command worked for me in bash 4.2.10 in Ubuntu 11.10. – jcollado Feb 27 '12 at 23:01