json - 在 JQ 中从外部文件中查找 ID
问题描述
我有一个查找文件,将 ID 从一个系统映射到另一个系统:
[
{
"idA": 2547,
"idB": "5d0bf91d191c6554d14572a6"
},
{
"idA": 2549,
"idB": "5b0473f93d4e53db19f8c249"
},
{
"idA": 2550,
"idB": "5d0bfabc8f20917b92ff07dc"
},
...
我有一个数据文件,其中包含来自以下系统之一的值和 ID:
[
{
"idB": "5d0bf91d191c6554d14572a6",
"description": "Description for 5d0bf91d191c6554d14572a6"
},
{
"idB": "5d0bf49e9236c57281811cfc",
"description": "Description for 5d0bf49e9236c57281811cfc"
},
{
"idB": "5d0bfabc8f20917b92ff07dc",
"description": "Description for 5d0bfabc8f20917b92ff07dc"
},
...
我想生成一个新的描述文件,并将它们的 ID 转换为idA
查找文件中的值。我试过这个:
jq --slurpfile idmap ids.json 'map( {"description":.description, "id": (.idB as $b|$idmap[][]|select(.idB==$b)|.idA) } )' descriptions.json
但它只产生一个空数组。
我必须双重取消引用$idmap
,因为 slurping 文件“将解析的 JSON 值的数组绑定到给定的全局变量”——所以只是这样做$idmap[]
会引发错误,jq: error (at descriptions.json:70): Cannot index array with字符串 "idB"。
谁能解释我在这里做错了什么?
解决方案
这是对所述问题的简洁明了的解决方案。
为简单起见,我们将首先使用以下方法构造一个包含相关映射的字典INDEX/2
:
INDEX($idmap[]; .idB) | map_values(.idA)
现在任务很简单:
(INDEX($idmap[]; .idB) | map_values(.idA)) as $dict
| map( {description, "idA": $dict[.idB] } )
这假定使用 --argfile idmap ids.json 的调用来避免由 --slurpfile 引起的不需要的“slurping”,但如果使用后者,那么您将使用$idmap[][]
原始问题中所述的代替。
由于示例片段不包含任何匹配的“idB”值,因此显示使用这些片段获得的输出几乎没有意义。
变化
如果其中的对象descriptions.js
有其他应该保留的键,那么以下变体可能是更有用的指南:
(INDEX($idmap[]; .idB) | map_values(.idA)) as $dict # or $idmap[][] as above
| map( .idA = $dict[.idB] | del(.idB) )
推荐阅读
- android - 麻省理工学院应用程序发明者休息在平板电脑上运行时返回错误
- macos - 如何将终端样式更改回默认值?
- javascript - 在javascript中计数和重置
- javascript - 使用纯javascript将鼠标悬停在视频上时如何播放视频
- ruby - 向 Middleman 添加自定义 Markdown
- c# - 用一个词多次拆分字符串?
- html - 在换行符中处理边距时,是否有更简单的“calc”替代方法?
- video-streaming - HLS 视频流和聊天消息同步
- ios - 将 AKAudioFile 拆分为由静音分隔的块
- vb.net - VB.NET 不能将 EOF 和 BOF 与 ADODB 记录集一起使用