I have a sed command that I want to use in a Makefile. It works in the terminal. The command is

sed -n '/[{]/,/[}]/{
 //end of block matching brace
}' myfile.txt

This results in these error messages from make:

/bin/sh: 2: Syntax error: Unterminated quoted string

If I add backslashes or place everything on one line I get

sed: -e expression #1, char 14: extra characters after command

Any help would be greatly appreciated.

  • Does it work if you escape all newlines and the \ that occurs at the end of one of the lines, so that you have a\\\ on that line?
    – Kusalananda
    Apr 19, 2020 at 11:16
  • Won't awk '/[{]/,/[}]/{print; if($0~/[}]/)print "//end of ..."}' do the same and fit on a single line? There probably are ways to achieve what you're trying to do, but I'm not able to figure out any standard way to do it.
    – mosvy
    Apr 19, 2020 at 11:32
  • @Kusalananda No.
    – mosvy
    Apr 19, 2020 at 11:43
  • @mosvy Yes, that worked! Thank you so much. I only had to use two dollar signs instead of one.
    – Theo
    Apr 19, 2020 at 12:10

3 Answers 3



$ sed -n -e '/[{]/,/[}]/{p; /[}]/ a\ //end of block matching brace' -e' }' file
If I add backslashes or place everything on one line I get
df }
 //end of block matching brace

Be aware of the TWO -e (expression) options needed because you need to terminate the append text. Not all sed versions allow for append text in the same line (my GNU sed does, my FreeBSD sed does not).

  • For BSD sed divide the a command up into two expressions, one ending a\ and one beginning //end.
    – Kusalananda
    Apr 19, 2020 at 12:07
  • Thank you! This works, but I think I will use @mosvy 's answer, as since its more portable.
    – Theo
    Apr 19, 2020 at 12:19
  • @ Kusalananda: unfortunately, I get an error message with your hint: sed: 1: "//end of block matching ...": invalid command code e
    – RudiC
    Apr 19, 2020 at 12:24
  • @RudiC Did you forget the -e? sed -n -e '/[{]/,/[}]/{p; /[}]/ a\' -e '//end of block matching brace' -e '}'
    – Kusalananda
    Apr 19, 2020 at 13:10
  • @Theo mosvy hasn't submitted an answer, but you could use it in a self-answer if you also explained it.
    – Kusalananda
    Apr 19, 2020 at 13:11

Whenever I am struggling with newlines, backslashes esp in makefiles, I reach for the G command in sed. What's more, it allows one to remain within Posix sed:

$ sed -e '/[{]/,/[}]/!d' -e '/[}]/G' -e 's|\n|&//end of block matching brace|' myfile.xt
  • My sed-fu isn't as strong as yours... what's special about G please?
    – roaima
    Apr 21, 2020 at 23:24
  • 1
    One doesn't need to slip in an escaped newline in the RHS of s/// and then the sed expression can be single lined. All this n still posixly. Apr 22, 2020 at 15:25

With gnu make and a shell that accepts $'' you can use an intermediate variable as make handles \eol differently outside recipes:

make  -f - <<\!
define mycmd
sed -n $$'/[{]/,/[}]/{\n\
 //end of block matching brace\n\
}' myfile.txt

.PHONY: default

Each line had \n\ added, and the solitary \ was doubled. Make converts the \eol outside recipes into a space, so it all ends up on one line, then the shell $'' converts the \n into real newlines. You don't have to use define to set the variable; MYCMD = sed... works similarly.

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.