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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 19:24:47  来源:igfitidea点击:

How to use sed in a Makefile

makefilebash

提问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 sedin 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 makeversion 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 sedversion:

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.shin the same folder as your Makefile that executes the sedcommand. 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_ownercould 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 --silentoption to make: remote_owner=$$($(MAKE) --silent remote.owner)

答案是添加以下--silent选项:remote_owner=$$($(MAKE) --silent remote.owner)

回答by Sjoerd

Use something else than #to separate parts.

使用其他东西而不是#分开零件。