通过有条件地覆盖第二个文件的部分来合并两个文件

时间:2018-06-06 16:08:36

标签: bash awk sed diff

我有两个配置文件,旧的和新的。 New是具有默认值的模板配置,可能还有其他变量。旧的是修改后的配置,其值必须保留。我需要制作一个新的修改配置:

  1. 如果旧版和新版都存在变量,请保留旧值
  2. 如果变量在旧时被注释掉,那么保持这样,反之亦然
  3. 如果变量仅存在于old中,请将其删除
  4. 如果变量仅存在于new中,请保留
  5. 旧修改

    $ cat old.cfg
    # var1 = 111
    # var2 = 123
    var3 = 111
    var4 = 123
    var5 = 123
    

    新默认配置

    $ cat new_default.cfg
    var1 = 111
    # var2 = 123
    var3 = 111
    # var4 = 111
    var6 = 111
    

    新修改的配置(所需)

    $ cat new.cfg
    # var1 = 111
    # var2 = 123
    var3 = 111
    var4 = 123
    var6 = 111
    

    #总是用空格分隔(因为配置编辑是手动的,我使用sed为此:sed -i -E 's/^#([^ ])/# \1/'),所以也许awk可以用于整个事情。现在我有这个awk 'FNR==NR{a[$1]++;next}!a[$1]' new_default.cfg old.cfg写下变量名(awk中的第一列),这对两个文件都很常见。

    =============================================== ====

    UPD: 最后我使用了下面的答案并对其进行了修改,以便现在更好地满足我的需求并且看起来更加丑陋。

    1. 接受两个参数,旧配置和修补配置的模板
    2. 确保在行的开头#之后有一个空格
    3. 确保每个=每边都有一个空格
    4. 确保每个实际评论都以两个#而不是一个
    5. 开头
    6. 发出awk命令:如果行以#开头 - >比较第二列; 以##开头 - >比较整条线;没有#开始 - >比较第一 柱
    7. #!/bin/bash
      for var in "$@"
      do
          cp $var $var.bak
          sed -i -E 's/^#([^ ])/# \1/' $var
          sed -i -E 's/(.?)(\s?)=(\s?)(.?)/\1 = \4/' $var
          sed -i -E 's/^#([^=]+)$/##\1/' $var
      done
      awk '{if(/^# /)k=$2;else if(/^## /)k=$0;else k=$1;}NR==FNR{a[k]=$0; next} 
      {print (k in a)?a[k]:$0}' $1 $2 > output.txt
      

3 个答案:

答案 0 :(得分:1)

如果要实现与特定于应用程序的逻辑的合并,获得所需逻辑的唯一可靠方法是自己实际构建它。因此:

background: asset-url(‘icon-arrow-left-large-orange.svg’) no-repeat center left

答案 1 :(得分:1)

awk救援!

$ awk       '{k=/^#/?$2:$1} 
     NR==FNR {a[k]=$0; next}
             {print (k in a)?a[k]:$0}' config.old config.new

# var1 = 111
# var2 = 123
var3 = 111
var4 = 123
var6 = 111

不确定您的样本输入/输出中是否包含所有测试。

答案 2 :(得分:1)

此答案假设您在#=周围始终有空格,如示例输入中所示:

awk '
    NR == FNR {if ($1 == "#") new_ignore[$2]; else new[$1] = $3; next }
    $1 == "#" { delete new[$2]; print; next }
    { old[$1] }
    $1 in new || $1 in new_ignore { print; next }
    END { for (key in new) if (!(key in old)) printf "%s = %s\n", key, new[key] }
' new_default.cfg old.cfg
# var1 = 111
# var2 = 123
var3 = 111
var4 = 123
var6 = 111