Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use sed in a Makefile

Tags:

bash

makefile

sed

I have tried putting the following in my Makefile:

@if [ $(DEMO) -eq 0 ]; then \     cat sys.conf | sed -e "s#^public_demo[\s=].*$#public_demo=0#" >sys.conf.temp; \ else \     cat sys.conf | sed -e "s#^public_demo[\s=].*$#public_demo=1#" >sys.conf.temp; \ fi 

but when I run make, I get the following error:

sed: -e expression #1, char 30: unterminated `s' command 

If I run the exact lines that contain sed in the console, they behave correctly.

Why am I getting this error and how can the problem be fixed?

like image 821
Tom Avatar asked Jun 29 '10 13:06

Tom


People also ask

How do I run a command in Makefile?

@anon58192932 That specific iteration, to execute a command, is usually done in a shell syntax fragment in a build recipe, so it occurs in the shell, rather than in make: for x in $(FILES); do command $$x; done . Note the doubled up $$ which passes a single $ to the shell.

How does sed work?

The sed program is a stream editor that receives its input from standard input, changes that input as directed by commands in a command file, and writes the resulting stream to standard output. A stream of ASCII characters either from one or more files or entered directly from the keyboard.

What is\ 1 in sed?

In both cases, the \1 refers to the characters captured by the escaped parentheses. In the third command, two capture groups are specified. They are referred to by using \1 and \2 .

What is sed script?

sed is a stream editor. A stream editor is used to perform basic text transformations on an input stream (a file or input from a pipeline). While in some ways similar to an editor which permits scripted edits (such as ed ), sed works by making only one pass over the input(s), and is consequently more efficient.


2 Answers

TL;DR: Use single quotes and use two $ signs. The expression is expanded twice, once by make and once by bash. The rest of this answer provides further context.

It might be the $ sign in the substitution that is interpreted by make as a variable. Try using two of them like .*$$#public_demo. Then make will expand that to a single $.

EDIT: This was only half the answer. As cristis answered: the other part is that one needs to use single quotes to prevent bash from expanding the $ sign too.

like image 111
Erik Edin Avatar answered Oct 09 '22 16:10

Erik Edin


I suggest you use single quotes instead of double quotes, the $ might be processed as a special char by make before running sed:

cat sys.conf | sed -e 's#^public_demo[\s=].*$#public_demo=0#' >sys.conf.temp; 
like image 20
cristis Avatar answered Oct 09 '22 14:10

cristis