在makefile中使用sed匹配和替换字符串

时间:2018-01-25 03:38:30

标签: regex sed makefile

我想在一堆MD和HTML文件中搜索以" id"开头的行。并替换字符串的任何实例" old"用字符串" new"。我从命令行开始使用以下内容。

find \( -name '*.md' -o -name '*.html' \) -exec sed -i '/id:/s/old/new/g' '{} \;

但是,我需要从Makefile运行命令。我之前从未做过任何事情。当我将同样的命令放入Makefile并尝试从那里执行时,它会失败。当我意识到我对make的了解有多少时,因为我天真地认为它是否可以从命令行工作,它可以从make中工作。我错了。所以我在这个Makefile中寻找一些类似的sed命令的例子,我想出了以下内容。这不会出错,但它也不会对我的文件做任何事情。所以,我不知所措。任何帮助表示赞赏!

switch_old_for_new:
    find \( -name '*.md' -o '*.html' \) -exec sed -i 's#^\(id: \)$(OLD)#\1$(NEW)#' '{}' \; 

注意:正如您可能看到的那样,我需要能够为" old"传递两个实际值。和"新"从命令行,所以我还需要在sed中有变量。所以我会这样执行:

make switch_old_for_new OLD=old NEW=new

1 个答案:

答案 0 :(得分:2)

似乎已经很晚了,在复制命令行时你的咖啡用完了;) 在你的第一个例子中唯一可疑的是'之前的多余的{}。所有其他事情在make中保持不变。在一个配方中,\没有特别的意义,也就是说,如果make在target:之后的一个tabulator前面的行中找到它,那么它应该真正逐字地运行到solo命令行。唯一值得注意的例外是在换行符之前的\,例如:

target:
    echo a very long \
    line with a \+newline in it

在这种情况下,make会将\(newline)作为指示,它应该将当前行与下一行(以及所有后续\(newline)连接)一起传递给shell,而不是单独的shell调用对于默认情况下的每个配方行。 (注意:只有选项卡,但 \(newline)将从提供给shell的字符串中删除 - 如果\(newline进入,你需要稍微使用变量方式。) 此外,所有类型的引用字符'"以及反向标记(SO赢得了允许我用语法字体编写)以及glob-characters {{1} },*不要调用任何特殊行为 - 它们会按原样传递给shell。 所以你的make文件看起来像:

?