unix 迭代嵌套循环并获取它们的值以构建一个新的JSON文件[关闭]

ikfrs5lh  于 2023-08-04  发布在  Unix
关注(0)|答案(2)|浏览(112)

已关闭。此问题需要更多focused。它目前不接受回答。
**希望改进此问题?**更新问题,使其仅针对editing this post的一个问题。

21小时前关闭
Improve this question
我在abc.env中有如下条目-

connection_name_1=xyz
connection_name_2=gsh
schema_1_connection_name_1=dsd
schema_2_connection_name_1=rwf
schema_1_connection_name_2=dfs

字符串
我想基于connection_name及其相关模式进行迭代,例如:

connection_name_1 will have-
schema_1_connection_name_1
schema_2_connection_name_1
connection_name_2 will have-
schema_1_connection_name_2


并将其存储到JSON文件中,看起来像这样-

"connection_specific_details": [
    {
        "connection_name": "xyz",
        "schemas": [
            {
                "dbUser": "dsd"
            },
            {
                "dbUser": "rwf"
            }
        ]
    },
    {
        "connection_name": "gsh",
        "schemas": [
            {
              "dbUser": "dfs"
            }
        ]
    }
]


请评论,如果它仍然是未知的,将尝试以不同的方式详细说明,但这是直截了当的json,我需要框架出给定的值在环境。

n8ghc7c1

n8ghc7c11#

TXR中的解决方案。

$ txr json.txr data
[{"schemas":[{"dbUser":"dsd"},{"dbUser":"rwf"}],"connection_name":"xyz"},
 {"schemas":[{"dbUser":"dfs"}],"connection_name":"gsh"}]

字符串
json.txr中的代码

@(collect)
connection_name_@cn=@cname
@  (trailer)
@  (collect)
schema_@{sn}_connection_name_@cn=@sname
@  (end)
@(end)
@(do
   (put-jsonl [mapcar (lambda (c slist)
                        #J^{"connection_name" : ~c,
                            "schemas" : [
                              ~*(mapcar (ret #J^{ "dbUser" : ~@1 }) slist)
                            ]})
                      [vec-list cname] sname]))


这是通过将数据刮擦到嵌套列表中来实现的。如果使用--lisp-bindings选项,我们可以看到捕获的变量,该选项在终止之前将绑定转储为Lisp格式。因此,我们再次看到输出,后面是绑定:

$ txr --lisp-bindings json.txr data
[{"schemas":[{"dbUser":"dsd"},{"dbUser":"rwf"}],"connection_name":"xyz"},
 {"schemas":[{"dbUser":"dfs"}],"connection_name":"gsh"}]
(cn "1" "2")
(cname "xyz" "gsh")
(sn ("1" "2") ("1"))
(sname ("dsd" "rwf") ("dfs"))


换句话说,数据被收集到并行列表中。一个包含连接号的列表cn,一个包含关联集合名的列表cname,一个包含与每个连接关联的模式号列表的列表sn,最后一个包含与每个连接关联的模式名列表的列表sname
我们不使用输出中的数字,所以我们只Mapcnamesname列表,因此我们的lambda函数接收一个c参数(连接名称)和一个slist参数(连接名称列表)。
在TXR Lisp中的JSON语法由#J表示。这是字面语法。它会评估为原生对象:浮点数、向量、散列(对于对象)、字符串、符号。我们可以使用准引号字符^来表示插值,其中值用~插入,用~*拼接。有两种方式拼接^#J会产生JSON语法,需要对其进行评估。这在某些宏中很有用。这里我们用#J^插值生成一个对象。
[vec-list cname]的目的是将列表强制转换为向量。如果mapcar最左边的序列是一个向量,则结果将是一个向量,这就是我们所需要的:put-jsonl会将一个向量转换成JSON向量表示法;它不接受列表。
在模式提取逻辑中使用了@(trailer)指令,这一点很重要。它被放置在connection_name_@cn...匹配项之后。它所做的是使匹配的其余部分成为尾随上下文,以便模式匹配器仅前进到connection_name_<n>=...行之后。如果没有@(trailer),则所有匹配的内容都将被视为从文本中提取出来并跳过。我们不能这样做,因为事情是重叠的:在给定的连接和它的模式之间存在其他的连接。
要打印缩进的JSON,我们可以这样修改程序:

$ txr  json.txr data
[
  {
    "schemas" : [
      {
        "dbUser" : "dsd"
      },
      {
        "dbUser" : "rwf"
      }
    ],
    "connection_name" : "xyz"
  },
  {
    "schemas" : [
      {
        "dbUser" : "dfs"
      }
    ],
    "connection_name" : "gsh"
  }
]


这是通过将*print-json-format*动态变量:

@(do
   (let ((*print-json-format* :standard))
     (put-jsonl [mapcar (lambda (c slist)
                          #J^{"connection_name" : ~c,
                              "schemas" : [
                                ~*(mapcar (ret #J^{ "dbUser" : ~@1 }) slist)
                              ]})
                        [vec-list cname] sname])))

1tu0hz3e

1tu0hz3e2#

这里是另一个TXR解决方案,它不构造一个转换为JSON的对象。它唯一使用的JSON支持是tojson函数,它将字符串对象转换为JSON语法,并对字符和其他东西进行所有正确的转义:
这将通过文本模板准确地生成示例输出:

$ txr json2.txr data
"connection_specific_details": [
    {
        "connection_name": "xyz"
        "schemas": [
            {
                "dbUser": "dsd"
            },
            {
                "dbUser": "rwf"
            }
        ]
    },
    {
        "connection_name": "gsh"
        "schemas": [
            {
                "dbUser": "dfs"
            }
        ]
    }
]

字符串
代码的提取部分几乎相同。然后有一个@(output)块:

@(collect)
connection_name_@cn=@cname
@  (trailer)
@  (collect)
schema_@{sn}_connection_name_@cn=@sname
@  (end)
@  (bind slen @(len sname))
@(end)
@(bind clen @(len cname))
@(output)
"connection_specific_details": [
@   (repeat :counter (ci 1))
    {
        "connection_name": @(tojson cname)
        "schemas": [
@           (repeat :counter (si 1))
            {
                "dbUser": @(tojson sname)
            }@(if (< si slen) ",")
@           (end)
        ]
    }@(if (< ci clen) ",")
@   (end)
]
@(end)


我们必须处理JSON中的逗号规则:列表或对象语法的最后一个元素后面不能跟着逗号。

相关问题