【问题标题】:Using sed for a generic substitutioner使用 sed 作为通用替换器
【发布时间】:2023-03-19 19:35:01
【问题描述】:

我收到了一个包含不同配置条目的文件 示例输入中的行:

       "configuration_name_1": "configuration_value_1"
  configuration_name_2 : configuration_value_2 
  "configuration_name_3": 'configuration_value_3'
  "configuration_name_4": configuration_value_4

这些值应该充当不同文件中的替代品(按位置和类型 - JSON、yaml 等)。无法为整个解决方案实现统一的文件类型,也不可能向主机添加额外的工具。

我已经设法在一个临时文件中将所有配置修剪为 key:value 格式。 示例:

configuration_name_1:configuration_value_1
configuration_name_2:configuration_value_2 
configuration_name_3:configuration_value_3

下一步是覆盖不同文件中的值。 example.yaml 文件包含(请记住,yaml 对缩进敏感):

  configuration_name_1: "test"
  configuration_name_2:  123 

example.yaml 必须改为:

  configuration_name_1: "configuration_value_1"
  configuration_name_2:  configuration_value_2

example.json 包含

{
 "configuration_name_3": "abcd"
 "configuration_name_4":  5555
}

example.json 必须改为:

{
 "configuration_name_3": "configuration_value_3"
 "configuration_name_4":  configuration_value_4
}

有没有办法覆盖目标文件中特定键的值,同时忽略格式?

【问题讨论】:

  • 请在您的问题中添加示例输入(无描述、无图像、无链接)以及该示例输入所需的输出(无评论)。
  • 添加了文件内容的当前状态和文件内容的目标状态。

标签: regex sed replace


【解决方案1】:

sed 用于对单个字符串执行简单的 s/old/new,仅此而已。对于其他任何你应该使用 awk 的东西,例如使用 GNU awk 为 gensub() 和第三个参数为 match():

$ cat tst.awk
NR == FNR {
    tag = gensub(/:.*/,"",1)
    val = gensub(/[^:]+:/,"",1)
    gsub(/^\s*["\047]?|["\047]?\s*$/,"",tag)
    gsub(/^\s*["\047]?|["\047]?\s*$/,"",val)
    tag2val[tag] = val
    next
}
match($0,/^(\s*([^:]+)[:[:space:]]+)(.*)$/,a) {
    tag = a[2]
    gsub(/^"|"$/,"",tag)
    if ( tag in tag2val ) {
        delim = (gsub(/^"|"$/,"",a[3]) ? "\"" : "")
        $0 = a[1] delim tag2val[tag] delim
    }
}
{ print }

$ cat foo.map
       "configuration_name_1": "configuration_value_1"
  configuration_name_2 : configuration_value_2
  "configuration_name_3": 'configuration_value_3'
  "configuration_name_4": configuration_value_4

$ awk -f tst.awk foo.map example.yaml example.json
  configuration_name_1: "configuration_value_1"
  configuration_name_2:  configuration_value_2
{
 "configuration_name_3": "configuration_value_3"
 "configuration_name_4":  configuration_value_4
}

如果您愿意,可以“就地”进行更改:

$ cat example.yaml
  configuration_name_1: "test"
  configuration_name_2:  123

$ cat example.json
{
 "configuration_name_3": "abcd"
 "configuration_name_4":  5555
}

$ awk -i inplace -f tst.awk foo.map example.yaml example.json

$ cat example.yaml
  configuration_name_1: "configuration_value_1"
  configuration_name_2:  configuration_value_2

$ cat example.json
{
 "configuration_name_3": "configuration_value_3"
 "configuration_name_4":  configuration_value_4
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-24
    • 1970-01-01
    • 2021-12-18
    • 2017-03-19
    • 2016-08-12
    • 2013-05-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多