2

我有以下在 Linux 命令提示符下工作的命令行:

vi /tmp/test.txt -s <( echo ":1 s/^\/\/ VERSION: .*$/\/\/VERSION: $(date)/g" )

它创建一个包含以下vim命令的临时文件(使用 Process Substitution):

:1 s/^\/\/ VERSION: .*$/\/\/ VERSION: $(date)/g

它打开文件/tmp/test.txt进行编辑并从先前创建的临时文件中执行命令。它找到第 1 行并用当前时间戳替换该行。它看起来有点像这样:

// VERSION: Fri Apr 12 21:20:03 CEST 2013
...
...

接下来我可以进行任何需要的编辑,只有当我决定保存文件时,所有更改才会提交到磁盘。首先更改磁盘上的文件,然后启动编辑器不是一个选项,因为文件将具有不同的时间戳,而内容本身没有更改。

到目前为止,它按设计/预期工作。

现在我试图将这个 vi 命令行移动到一个 make 文件中,这就是我失败的地方。我尝试了一个$(shell .....)构造,但是 make 向我抛出了错误。

edit:
        $(shell vi $(src).cpp -s <( echo ":1 s/^\/\/ VERSION: .*$/\/\/VERSION: $(date)/g" )

我试图弄清楚 Makefile 中的行应该如何读取额外的引号和括号,但我还没有解决它。

我正在运行 Ubuntu Linux 12.10 和 GNU Make 3.81

vi project.cpp -s <( echo ":1 s/^\/\/ VERSION: .*$/\/\/VERSION: $(date)/g" )

Make 似乎不喜欢“过程替换”结构<( command )。我不想使用额外的(真实)文件。

€ make edit
vi project.cpp -s <( echo ":1 s/^\/\/ VERSION: .*$/\/\/VERSION: $(date)/g" )
/bin/sh: 1: Syntax error: "(" unexpected
make: *** [edit] Error 2
4

1 回答 1

11

在制作配方中使用$(shell ...)实际上是不正确的。你已经在 shell 中了……只需直接输入你想要的命令。尝试使用 make$(shell ...)函数只会增加混乱。你将不得不$通过写作来逃避$$

您还有另一个问题:总是使用 bash 特定的构造 ( )make调用它的脚本。/bin/sh<(...)

当然,更大的问题是您为什么要使用可视化编辑器 vi 来进行这样的自动更改,而不是sed专门为它设计的。我会将其重写为:

edit:
        sed -i "1 s,^// VERSION: .*,// VERSION: $$(date)," $(src).cpp

如果您真的想使用 vi,则必须执行以下操作:

SHELL := /bin/bash

edit:
        vi '$(src).cpp' -s <( echo ":1 s/^\/\/ VERSION: .*$$/\/\/VERSION: $$(date)/g" )
于 2013-04-12T19:45:30.270 回答