【问题标题】:Sed - replace value in file with regex match in another fileSed - 用另一个文件中的正则表达式替换文件中的值
【发布时间】:2017-09-17 03:22:15
【问题描述】:

我正在尝试在构建过程中编写 bash 脚本,其中我们只有几个工具(如 grep、sed、awk),并且我正在尝试用正则表达式匹配中的值替换 ini 文件中的值在另一个。

所以,我在 export_vars.h 文件中匹配“^export ADDRESS=VALUE”之类的内容,并将 VALUE 放入名为 config.ini 的 ini 文件中,并与“ADDRESS=[REPLACE]”对齐。所以,我试图用 bash 中的一个命令将 [REPLACE] 替换为 VALUE。

我发现 sed 可以使用像

这样的命令将整个文件插入到另一个文件中
sed -i -e "/[REPLACE]/r export_vars.h" config.ini

我需要以某种方式改进此命令,使其仅从 export_vars.h 读取模式匹配。有人知道怎么做吗?

【问题讨论】:

  • 澄清一下,您希望export_vars.h 中的行(例如export ADDRESS=VALUE)替换config.ini 中的行(例如ADDRESS=VALUE)?我假设您在此处尝试匹配的是 ADDRESS 并且您希望在此示例中替换 VALUE?
  • 是 - 或者只是将 ini 文件中的 [REPLACE] 替换为 VALUE。我想两者都行。

标签: regex bash awk sed grep


【解决方案1】:

sed 用于在单个行上进行简单替换,仅此而已。您需要查看 awk 以了解您正在尝试做的事情。比如:

awk '
BEGIN { FS=OFS="=" }
NR==FNR { 
    if ( $1 == "export ADDRESS" ) {
        value = $2
    }
    next
}
{ sub(/\[REPLACE\]/,value); print }
' export_vars.h config.ini

当然,未经测试,因为您没有提供可测试的样本输入/输出。

【讨论】:

  • 谢谢,效果很好。显然,需要更多地学习 awk,因为我们还有其他类似的任务。
  • 不客气。要学习 awk,请阅读 Arnold Robbins 所著的《Effective Awk Programming, 4th Edition》一书。所有其他书籍都已过时,所有在线教程都存在错误和/或误导性。如果您正在考虑在 sed 中使用除 s、g 和 p(带有 -n)以外的结构的任何事情,那么您使用的工具是错误的。 Sed 适用于s/old/new/,仅此而已,即使这样也有一些警告(例如,它不理解字符串)。 1970 年代中期,当 awk 被发明时,所有其他神秘的 sed 构造都已过时,如今仅用于脑力锻炼,而不再用于生产软件。
  • 我从没听说过它,但从标题 2 件事浮现在脑海中:1)您不需要任何书来告诉您如何正确使用 sed(s/old/new/ - 完成!), 2) 里面有Hacks 这个词——有谁会想学习如何编写黑客而不是惯用正确、优雅的代码?哦,我明白了,它是由在 thegeekstuff 上用可怕的 awk“教程”编写的 - 不,像瘟疫一样避免这种情况。
  • @EdMorton,对,我在任何在线书店都没有找到它......他写道 我已经添加 1 和 0 超过 17 年了IT行业 ...
  • 我想知道当他添加1 加上0 时,他会得到什么答案:-)。看看他的教程3. Awk RS Example: Record Separator variable。他说Awk RS defines a line - 不,它没有,它分隔记录。他显示RS="\n\n" 读取空白行分隔的记录-不,您不使用RS=""RS="\n\n" 由于多字符RS,无论如何都是gawk 特定的。我过去曾对他网站上的示例进行过更正,但他不听。
【解决方案2】:

awk 中的另一个:

$ awk '/ADDRESS/{if(a!="")$0=a;else a=$NF}NR>FNR' export_vars.h config.ini
ADDRESS=VALUE

解释:

$ awk '
/ADDRESS/ {                 # when ADDRESS is found in record
    if(a!="") $0=a          # if a is set (from first file), use it
    else a=$NF }            # otherwise set a with the last field
NR>FNR                      # print all record of the last file
' export_vars.h config.ini  # mind the order

此解决方案不能容忍 = 周围的空间,因为 $0 已替换为另一个文件中的 $NF

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-23
    • 2017-05-10
    • 2020-04-22
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 2019-05-18
    相关资源
    最近更新 更多