【发布时间】:2018-01-26 00:08:05
【问题描述】:
我想在一堆 MD 和 HTML 文件中搜索以“id”开头的行,并将字符串“old”的任何实例替换为字符串“new”。我使用以下命令从命令行进行了这项工作。
find \( -name '*.md' -o -name '*.html' \) -exec sed -i '/id:/s/old/new/g' '{} \;
但是,我需要从 Makefile 运行命令。我以前从未对make做过任何事情。当我将相同的命令放入 Makefile 并尝试从那里执行它时,它会失败。那时我意识到我对 make 知之甚少,因为我天真地认为如果它在命令行中工作,它会在 make 中工作。我错了。因此,我在这个 Makefile 中寻找一些执行类似操作的 sed 命令示例,我想出了以下内容。这不会出错,但它也不会对我的文件做任何事情。所以,我很茫然。任何帮助表示赞赏!
switch_old_for_new:
find \( -name '*.md' -o '*.html' \) -exec sed -i 's#^\(id: \)$(OLD)#\1$(NEW)#' '{}' \;
注意:正如您可能看到的,我需要能够从命令行为“旧”和“新”传入两个实际值,因此我还需要在 sed 中包含变量。所以我会这样执行:
make switch_old_for_new OLD=old NEW=new
【问题讨论】:
-
变量不在单引号内展开,见stackoverflow.com/questions/7680504/… ...另外,我认为在makefile中,你需要使用
$$而不是$ -
另外,由于您正在传递变量,您可能不知道它们的内容,这可能与 sed 元字符发生冲突。请参阅stackoverflow.com/questions/29613304/…
-
您将
id:更改为\(id: \),它不需要括号,并且在冒号后还需要一个空格。您将其考虑到替换中,而不是在一行的任何位置匹配它。这可能是微不足道的,但也不可能。 -
关于引用的评论(第一条评论)不正确。作者试图在其配方中使用 make 变量,而不是 shell 变量(请参阅设置 make 变量的示例 make 命令行)。所以他们不想逃避
$。此外,make 一点也不关心引号,所以在这里使用单引号而不是双引号是可以的。您关于 sed 元字符的观点是有效的,尽管作者可能知道可能的内容是什么。 -
如果您提供的不是通用的“失败”,而是提供有关确切发生情况的信息,那将非常有帮助。你收到错误信息了吗?他们是什么?你看到make打印的命令了吗?还有其他输出吗?