按块名称合并两个 ini 文件

mon*_*onk 2 awk ini

如何合并两个ini文件的两个块?

嗨,我有两个 ini 文件,它们以块的形式存储数据,如下所示:

 -->cat f1
[default]
a1=1
b1=2
c1=3

[foo]
d=1
e1=5


 -->cat f2
[default]
a2=5
b2=6

[foo]
c2=7
d2=8
e2=9

[bar]
f2=10
Run Code Online (Sandbox Code Playgroud)

我需要按如下方式合并这两个文件:

[default]
a1=1
b1=2
c1=3
a2=5
b2=6

[foo]
d=1
e1=5
c2=7
d2=8
e2=9


[bar]
f2=10
Run Code Online (Sandbox Code Playgroud)

老实说,我不知道从哪里开始,需要什么逻辑或工具。

我试图获得方向的一些愚蠢的事情是:

awk 'NR==FNR{a[$0]=$0;next} $0 in a{print}' f1 f2
[default]

[foo]

awk -vRS='' '{$1=$1}1' f1 f2 |awk '!a[$1]++'
[default] a1=1 b1=2 c1=3
[foo] d=1 e1=5
[bar] f2=10
Run Code Online (Sandbox Code Playgroud)

anu*_*ava 5

使用awk你可以这样做:

awk '/^$/{
   next
}
/^\[.*\]$/{
   hdr = $0
   next
}
a[hdr] != "" {
   a[hdr] = a[hdr] ORS $0
   next
}
{
   a[hdr] = $0
   seq[++n] = hdr
}
END {
   for (i=1; i<=n; i++)
      print seq[i] ORS a[seq[i]] (i<n ? ORS : "")
}' f1 f2
Run Code Online (Sandbox Code Playgroud)

[default]
a1=1
b1=2
c1=3
a2=5
b2=6

[foo]
d=1
e1=5
c2=7
d2=8
e2=9

[bar]
f2=10
Run Code Online (Sandbox Code Playgroud)

细节:

  • /^$/ 匹配我们忽略的所有空行
  • /^\[.*\]$/我们存储在hdr变量中的匹配标头名称
  • a[hdr] != "" { ... }当我们已经处理hdr过一次时,我们在a索引为的数组中添加一个新行和当前行hdr
  • 否则,我们只是将当前行存储在a索引为 的数组中hdr。我们还存储hdr在另一个seq由递增数字索引的数组中以按顺序打印数据
  • END块中,我们遍历seq数组并打印每个标题和详细信息块。如果我们有更多数据要处理,我们会附加一个换行符。

  • `ord` 是某些 awks 和 `ordchr` gawk 扩展中的函数名称。为了可移植性,对数组使用不同的名称。 (2认同)