首页 > 解决方案 > 使用 Bash 将值从一个文件映射到另一个文件

问题描述

所以我有两个文件,如下所列,我刚刚添加了 2 个示例,但是我在 file1 中有近 100 行,其格式如下所列。

想法是 file2 的变量用作我们内部脚本之一的源,目前我们正在手动将数据从 file1 填充到 file2 中,因为我们正在手动映射值。

我想知道这是否可以通过 Bash 脚本来实现,以识别 file1 的关键字并将它们与 file2 的关键字匹配,并将 file1 的匹配关键字的值附加到 file2 的匹配键中。

文件 1

system-service:10/AF/GH/100-2020
mint-value-daemon:10/GH/KL-19GA1-2020
event-count-svc:10/LL/GH/LL-2020
node-daemon:ABCD_201612_1900_139

文件 2

MINT_SERVICE=10/GH/KL-19GA1-2020 //value2 from file1
SYSTEM_SERVICE=10/AF/GH/100-2020 //Value1 from file1
EVENT_SERVICE=svc:10/LL/GH/LL-2020 //value3 from file1
NODE_SERVER_TAG=ABCD_201612_1900_139 //value 4 from file1

注意:请注意,file1 中的关键字通常是 2-3 个带有连字符的单词,所以我在考虑部分匹配关键字,例如 file2 中的事件与 file1 中的事件,并获得相应的值。

标签: bashshellscripting

解决方案


如果file2需要从头开始创建:

awk -F: -v OFS='=' '{
    split($1, a, "-")
    print toupper(a[1])"_SERVICE", $2
}' file1 > file2

如果file2已经有需要覆盖的变量:

#! /usr/bin/env bash
awk -F: -v OFS='=' '{
    if (FNR == NR) {
        split($1, a, "-")
        var[toupper(a[1])] = $2
    } else {
        split($0, a, "=")
        split(a[1], b, "_")
        if (var[b[1]] != "") {
            print a[1], var[b[1]]
        } else {
            print
        }
    }
}' file1 file2 > file2_new

mv file2_new file2

第二个片段解释:

1)awk逐行循环输入文件。
2)这样做时,$0 包含完整行的值。$1, $2, $3... 包含单独的:分隔值。我们要求:在 arg 中使用分隔符-F:
3) NR 是一个变量,包含它当前所在的行号。
4)当我们向 awk 输入 2 个文件时,它有点不同。NR当我们转到下一个文件时重置为 0。 FNR是一个变量,无论它通过什么文件,它都会不断增加。
5)条件检查FNR == NR意味着我们在第一个文件上。

以file1为例,假设我们在线

mint-value-daemon:10/GH/KL-19GA1-2020
$0 = mint-value-daemon:10/GH/KL-19GA1-2020
$1 = mint-value-daemon
$2 = 10/GH/KL-19GA1-2020


6) 在这个条件语句中,我们使用 split() 函数将 $1 拆分-为一个名为 的数组a

所以基本上这一行:

split($1, a, "-")

给我们:

a[1] = mint
a[2] = value
a[3] = daemon

我们现在使用一个关联数组,名为var.

var[toupper(a[1])] = $2

这将值存储$2在键上,MINT

var["MINT"] = 10/GH/KL-19GA1-2020

这样,它将每个此类元素的值存储在 file1 中。

当条件FNR == NR变为假时,即我们开始遍历第二个文件,我们遵循类似的方法。

记住文件分隔符仍然是:,它不是 file2 中的分隔符。

所以在其他方面:

假设我们在线:

MINT_SERVICE=10/GH/KL-19GA1-2020 //value2 from file1

我们用:

split($0, a, "=")

这给了我们:

a[1] = MINT_SERVICE
a[2] = 10/GH/KL-19GA1-2020 //value2 from file1

然后a[1]我们再次使用 split based on _

split(a[1], b, "_")

这给了我们:

b[1] = MINT
b[2] = SERVICE

现在:

if (var[b[1]] != "") {
    print a[1], var[b[1]]
} else {
    print
}

var在我们存储值的数组中,当FNR == NR为真时,

我们检查是否

var["MINT"] != ""

如果这是真的,

print a[1], var[b[1]] 

打印:

MINT_SERVICE=10/GH/KL-19GA1-2020

的原因=-v OFS='='which 是 的分隔符print

在其他:

print

这与

print $0

即如果这个值不是一个键,var打印它而不做任何修改。


所有这些输出都转到file2_new.

最后我们重命名file2_newfile2.


推荐阅读