You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让awk转义文件分隔符=?properties文件对比异常问题

问题描述

我需要对比并合并两个properties文件的差异,现有以下文件内容:

old1.properties

# comment
url=https://test.org/#,https://test.org:id=123

old2.properties

old-key1=value1
old-key3=value3
old-key4=value4

new1.properties

# comment
url=#

new2.properties

old-key1=value1
new-key2=value2
old-key3=value3
old-key4=value4

期望合并结果

  • 合并old1与new1的结果:
# comment
url=https://test.org/#,https://test.org:id=123
  • 合并old2与new2的结果:
old-key1=value1
new-key2=value2
old-key3=value3
old-key4=value4

我使用了以下awk命令进行合并:

awk -F= 'NR==FNR {if ($2!="") a[$1]=$2; next} $1 in a {$2=a[$1]} {print $0}' OFS== old.properties new.properties >old_new.txt

但URL中的=被误解析为字段分隔符,得到错误结果:

url=https://test.org,https://test.org:id

请问如何让awk避免将URL内的=当成分隔符?


解决方案

核心问题是原命令用-F=将所有=都视为字段分隔符,但properties文件的键值对中只有第一个=是键与值的分隔符,后续的=属于值的一部分。只需修改awk逻辑,仅以第一个=作为分割依据即可解决。

方法1:通过字符串替换提取键和值

awk 'NR==FNR {
    # 跳过注释行,仅处理包含=的有效键值行
    if ($0 !~ /^#/ && $0 ~ /=/) {
        # 提取第一个=之前的内容作为键
        key = $0; sub(/=.*/, "", key)
        # 提取第一个=之后的所有内容作为值
        val = $0; sub(/^[^=]+=/, "", val)
        if (val != "") a[key] = val
    }
    next
}
{
    if ($0 !~ /^#/ && $0 ~ /=/) {
        key = $0; sub(/=.*/, "", key)
        # 若键存在于旧文件中,替换当前行的值部分
        if (key in a) {
            sub(/=.*/, "=" a[key])
        }
    }
    print $0
}' old.properties new.properties > old_new.txt

方法2:用正则限定字段分隔符为第一个=

利用awk支持正则作为字段分隔符的特性,仅匹配第一个=:

awk -F'^([^=]+)=' '{
    NR==FNR {
        if ($2 != "") a[$1] = $2
        next
    }
    if ($1 in a) {
        $0 = $1 "=" a[$1]
    }
    print $0
}' old.properties new.properties > old_new.txt

两种方法都能精准识别键值对的分隔边界,不会破坏URL中包含的=,最终得到符合预期的合并结果。


内容的提问来源于stack exchange,提问作者user11705123

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 07:43:17