如何在Makefile中使用sed

时间:2010-06-29 13:17:41

标签: makefile bash

我已尝试在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

但是当我运行 make 时,我收到以下错误:

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

如果我在控制台中运行包含sed的确切行,则它们的行为正确。

为什么我会收到此错误以及如何解决问题?

6 个答案:

答案 0 :(得分:26)

可能是替换中的$符号被make解释为变量。尝试使用其中两个,例如。* $$#public_demo 。然后make会将它扩展为单个$。

编辑:这只是答案的一半。正如cristis回答:另一部分是需要使用单引号来阻止bash扩展$符号。

答案 1 :(得分:7)

我建议您使用单引号而不是双引号,在运行sed之前,$可能会被make作为特殊字符处理:

cat sys.conf | sed -e 's#^public_demo[\s=].*$#public_demo=0#' >sys.conf.temp;

答案 2 :(得分:3)

我机器中的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

sed版本:

$ sed --version
GNU sed version 4.2.1

我必须为$添加反斜杠,以防止sed将其作为行尾:

cat sys.conf | sed -e 's#^public_demo[\s=].*\$$#public_demo=0#' >sys.conf.temp

答案 3 :(得分:1)

我尝试了双$$符号,但它在我的问题中没有用,可能$$$$$$$$$$$$可能有效,因为我的Makefile会调用其他Makefile等等。但我找到了一个更好的解决方案:

在与执行replacer.sh命令的Makefile相同的文件夹中创建一个shell文件sed。用

给它可执行位
chmod +x replacer.sh

现在您可以在Makefile中调用此文件:

./replacer.sh

答案 4 :(得分:0)

使用#之外的其他内容来分隔各个部分。

答案 5 :(得分:0)

我在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

例如,通过添加调试消息,我发现local_owner设置为:

make[1]: Entering directory `/home/jcomeau/rentacoder/jh'
jcomeau

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