如何在 Makefile 中使用 sed

发布于 2024-09-07 10:46:22 字数 473 浏览 4 评论 0原文

我尝试将以下内容放入我的 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 的确切行,它们行为正确。

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

夏雨凉 2024-09-14 10:46:37

我尝试了双 $$ 符号,但它对我的问题不起作用,可能是 $$$$$$$$$$$$ 会起作用,因为我的 Makefile 调用其他 Makefile 等等。但我找到了更好的解决方案:

在执行 sed 命令的 Makefile 所在的同一文件夹中创建一个 shell 文件 replacer.sh。给它可执行位

chmod +x replacer.sh

现在你可以在你的 Makefile 中调用这个文件:

./replacer.sh

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
给我一枪 2024-09-14 10:46:35

当前的答案没有解决我在 makefile 中使用 sed 时遇到的一个问题,所以我将在这里解释一下。我像这样填充 Bash 变量:remote_owner=$$($(MAKE) remote.owner),然后在我的 sed 替换中使用这些变量。问题是,由于我的规则设置方式复杂,remote_owner 可能有 make 自己的输出,给我错误:

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 选项来 make: remote_owner=$$($(MAKE) --silent remote.owner)

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)

东北女汉子 2024-09-14 10:46:33

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

Use something else than # to separate parts.

月光色 2024-09-14 10:46:31

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

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
岁月无声 2024-09-14 10:46:29

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

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

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;
许你一世情深 2024-09-14 10:46:28

TL;DR:使用单引号使用两个$符号。该表达式被扩展两次,一次由 make 扩展,一次由 bash 扩展。这个答案的其余部分提供了进一步的上下文。

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文