json - jq中根据相似ID对象合并文件并改造数据
问题描述
前言:如果 jq 无法做到以下几点,那么我完全接受它作为答案,并将尝试用 bash 强制执行此操作。
我有两个文件,其中包含一些 ID,通过一些按摩,应该能够组合成一个文件。我也会添加一些内容(如输出所示)。本质上,“mitre_test”应该与“sys_id”进行比较。比较时,来自 in2.json 的“mitreid”在输出中变成了 technology_ID(通常是每个输出对象的统一字段)。
注意事项:
在 in1.json 中放置了一些垃圾“desc”值,以确保它尽可能编程,并且在我正在使用的真实输入文件中实际上有许多垃圾输入。
一些 mitre_test 值有对并且不在真实数组中。我可以拆分这些并将它们分开,但发现自己丢失了 in1.json 中的其他信息。
请注意,输出的“元数据”中包含来自 in1.json 的“数字”值,并以奇怪的方式存储(但接收工具需要的方式)。
in1.json
[
{
"test": "Execution",
"mitreid": "T1204.001",
"mitre_test": "90b"
},
{
"test": "Defense Evasion",
"mitreid": "T1070.001",
"mitre_test": "afa"
},
{
"test": "Credential Access",
"mitreid": "T1556.004",
"mitre_test": "14b"
},
{
"test": "Initial Access",
"mitreid": "T1200",
"mitre_test": "f22"
},
{
"test": "Impact",
"mitreid": "T1489",
"mitre_test": "fa2"
}
]
in2.json
[
{
"number": "REL0001346",
"desc": "apple",
"mitre_test": "afa"
},
{
"number": "REL0001343",
"desc": "pear",
"mitre_test": "90b"
},
{
"number": "REL0001366",
"desc": "orange",
"mitre_test": "14b,f22"
},
{
"number": "REL0001378",
"desc": "pineapple",
"mitre_test": "90b"
}
]
输出:
[{
"techniqueID": "T1070.001",
"tactic": "defense-evasion",
"score": 1,
"color": "",
"comment": "",
"enabled": true,
"metadata": [{
"name": "DET_ID",
"value": "REL0001346"
}],
"showSubtechniques": true
},
{
"techniqueID": "T1204.001",
"tactic": "execution",
"score": 1,
"color": "",
"comment": "",
"enabled": true,
"metadata": [{
"name": "DET_ID",
"value": "REL0001343"
},
{
"name": "DET_ID",
"value": "REL0001378"
}],
"showSubtechniques": true
},
{
"techniqueID": "T1556.004",
"tactic": "credential-access",
"score": 1,
"color": "",
"comment": "",
"enabled": true,
"metadata": [{
"name": "DET_ID",
"value": "REL0001366"
}],
"showSubtechniques": true
},
{
"techniqueID": "T1200",
"tactic": "initial-access",
"score": 1,
"color": "",
"comment": "",
"enabled": true,
"metadata": [{
"name": "DET_ID",
"value": "REL0001366"
}],
"showSubtechniques": true
}
]
我假设我要在 mitre_test 上使用类似的东西进行一些拆分.mitre_test |= split(","))
,并且我假设有一些连接,但是这样做会导致数据丢失或数据混淆。您会注意到输出中的静态数据也存在,但可能很容易放入,因此问题不大。
编辑:减少了一些匹配 ID,以便在分析 in1 和 in2 文件时更容易查看。还简化了两个输入以具有相似的结构,以便以后更容易理解答案。
解决方案
要求有些不透明,但很明显,如果任务可以通过计算机完成,则可以使用 jq 完成。
从描述中可以看出,问题的一个不寻常的方面是 in1.json 定义的“字典”必须通过拆分 CSV(逗号分隔值)的键名来派生。因此,这里有一个 jq def 可以做到这一点:
# Input: a JSON dictionary for which some keys are CSV,
# Output: a JSON dictionary with the CSV keys split on the commas
def refine:
. as $in
| reduce keys_unsorted[] as $k ({};
if ($k|index(","))
then ($k/",") as $keys
| . + ($keys | map( {(.): $in[$k]}) | add)
else .[$k] = $in[$k]
end );
您可以通过运行查看其工作原理:
INDEX($mitre.records[]; .mitre_test) | refine
使用 jq 的调用,例如:
jq --argfile mitre in1.json -f program.jq in2.json
对于问题的加入部分,有很多关于SO的相关问答,例如
推荐阅读
- java - Eclipse:必须声明元素类型“上下文”
- amazon-web-services - 什么可以在“固定”时间阻止我的码头流程?
- python - 使用 Python 在 JSON 文件中的数组中添加键
- python-2.7 - 为什么在 trigger_dag 之后任务在 Airflow 1.10.2 中停留在 None 状态
- java - InputStreamReader 只返回一半的 html 文档
- animation - 如何使用“维度”在地理服务器中制作动画
- android - 将应用程序升级到 64 位 Apk anaylzer 后,lib 中只有 32 位
- java - kafka消费者收到一条之前消费过的消息
- php - php过滤器多维数组
- ajax - Kendo asp .net MVC 未在 kendo 网格上显示记录