【问题标题】:Match and replace string with sed in makefile在makefile中用sed匹配和替换字符串
【发布时间】: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打印的命令了吗?还有其他输出吗?

标签: regex sed makefile


【解决方案1】:

看来时间不早了,在复制命令行进行制作时,您的咖啡用完了;) 在您的第一个示例中,唯一可疑的是在 {} 之前多余的 '。所有其他的东西在 make 中运行不变。在配方中,\ 没有特殊含义,也就是说,如果 make 在 target: 之后的制表符前面的行中找到它,那么它应该真正逐字运行到单独的命令行。唯一值得注意的例外是在换行符之前的\,例如:

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

在这种情况下,make 将\(newline) 作为指示,它应该将当前行与下一行(以及所有后续的\(newline) 连接)一起传递给shell,而不是为每个配方行单独调用shell在默认情况下。 (注意:只有标签但 not \(newline) 将从提供给 shell 的字符串中删除 - 如果 \(newline 妨碍您,您需要稍微使用变量。) 此外,所有类型的引用字符 '," 以及反引号(不允许我用语法字体编写)以及全局字符 *,? 不要调用任何类型的特殊行为 - 它们按原样传递给 shell。 所以你的 make 文件可能看起来像:

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

【讨论】:

  • 我在另一台笔记本电脑上有实际的命令,所以我手动输入它并在省略第二个 ' 字符时出错。实际的命令确实有它。不过已经很晚了,我错过了咖啡哈哈谢谢!!
猜你喜欢
  • 2017-03-20
  • 2015-12-18
  • 1970-01-01
  • 1970-01-01
  • 2016-04-29
  • 1970-01-01
  • 2016-08-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多