Reputation: 7223
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?
Upvotes: 30
Views: 40293
Reputation: 20845
I tried double $$
sign but it didn't work in my problem, maybe $$$$
or $$$$$$$$
would have worked, because my Makefile calls other Makefiles and so on. But I found a better solution:
Create a shell file replacer.sh
in the same folder as your Makefile that executes the sed
command. Give it executable bit with
chmod +x replacer.sh
Now you can call this file in your Makefile:
./replacer.sh
Upvotes: 0
Reputation: 690
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.
Upvotes: 37
Reputation: 664
The make
version in my machine is:
$ make --version
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for x86_64-redhat-linux-gnu
And the sed
version:
$ sed --version
GNU sed version 4.2.1
I must add backslash for $
to prevent sed taking it as end of line:
cat sys.conf | sed -e 's#^public_demo[\s=].*\$$#public_demo=0#' >sys.conf.temp
Upvotes: 3
Reputation: 38432
one problem I had with using sed in a makefile isn't addressed by the current answers, so I'll explain it here. I was populating Bash variables like so: remote_owner=$$($(MAKE) remote.owner)
and then using those variables in my sed substitution. problem is, due to the convoluted way my rules are set up, remote_owner
could have make's own output in it, giving me the error:
sed: -e expression #1, char 69: unknown option to `s'
make: *** [alter_table_local.sql] Error 1
for example, by adding debugging messages, I found local_owner set to:
make[1]: Entering directory `/home/jcomeau/rentacoder/jh'
jcomeau
the answer was to add the --silent
option to make: remote_owner=$$($(MAKE) --silent remote.owner)
Upvotes: 0
Reputation: 1995
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;
Upvotes: 9