bash - 使用 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 中的事件,并获得相应的值。
解决方案
如果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_new
为file2
.
推荐阅读
- mysql - MySQL:GROUP BY 和 ORDER BY 最新值
- r - R 会话在 randtest {ade4} 后中止
- android - 如何编写代码(当您按下按钮时,您无法再次选择)
- sass - 在 SASS 中,如何从函数返回列表?
- cookies - Laravel Cookies 中的额外字符串和管道字符
- ios - 无法从 swift 中的 JSON 字典数组中获取值
- reactjs - 这是什么警告,我该如何解决?
- database - 在redis中散列哈希
- reactjs - 如果组件包含图像元素,则会给出类型错误
- azure - 无法解析 Azure 自动化 SMTP 远程名称