bash 如何在 Makefile 中使用 sed
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3140974/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to use sed in a Makefile
提问by Tom
I have tried putting the following in my Makefile:
我尝试将以下内容放入我的 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:
但是当我运行make 时,出现以下错误:
sed: -e expression #1, char 30: unterminated `s' command
If I run the exact lines that contain sed
in the console, they behave correctly.
如果我运行sed
控制台中包含的确切行,它们的行为是正确的。
Why am I getting this error and how can the problem be fixed?
为什么我会收到此错误以及如何解决问题?
回答by Erik Edin
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 $.
可能是替换中的 $ 符号被 make 解释为变量。尝试使用其中的两个,例如.*$$#public_demo。然后 make 将其扩展为单个 $。
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.
编辑:这只是答案的一半。正如克里斯蒂斯回答的那样:另一部分是需要使用单引号来防止 bash 也扩展 $ 符号。
回答by cristis
I suggest you use single quotes instead of double quotes, the $
might be processed as a special char by make before running sed:
我建议您使用单引号而不是双引号,$
在运行 sed 之前,make 可能会将其作为特殊字符处理:
cat sys.conf | sed -e 's#^public_demo[\s=].*$#public_demo=0#' >sys.conf.temp;
回答by jiych.guru
The make
version in my machine is:
make
我机器上的版本是:
$ 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
版本:
$ sed --version
GNU sed version 4.2.1
I must add backslash for $
to prevent sed taking it as end of line:
我必须添加反斜杠 for$
以防止 sed 将其作为行尾:
cat sys.conf | sed -e 's#^public_demo[\s=].*$$#public_demo=0#' >sys.conf.temp
回答by rubo77
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:
我尝试了双重$$
签名,但它在我的问题中不起作用,也许$$$$
或$$$$$$$$
本来可以工作,因为我的 Makefile 调用了其他 Makefile 等等。但我找到了一个更好的解决方案:
Create a shell file replacer.sh
in the same folder as your Makefile that executes the sed
command. Give it executable bit with
replacer.sh
在与执行sed
命令的Makefile 相同的文件夹中创建一个 shell 文件。给它可执行位
chmod +x replacer.sh
Now you can call this file in your Makefile:
现在你可以在你的 Makefile 中调用这个文件:
./replacer.sh
回答by jcomeau_ictx
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:
我在 makefile 中使用 sed 时遇到的一个问题目前的答案没有解决,所以我将在这里解释。我像这样填充 Bash 变量:remote_owner=$$($(MAKE) remote.owner)
然后在我的 sed 替换中使用这些变量。问题是,由于我的规则设置方式复杂,remote_owner
可能会有自己的输出,给我错误:
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:
例如,通过添加调试消息,我发现 local_owner 设置为:
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)
答案是添加以下--silent
选项:remote_owner=$$($(MAKE) --silent remote.owner)
回答by Sjoerd
Use something else than #
to separate parts.
使用其他东西而不是#
分开零件。