【问题标题】:Linking json objects on generated GUID values在生成的 GUID 值上链接 json 对象
【发布时间】:2020-07-17 15:52:19
【问题描述】:

我正在寻找一种方法来自动完成在随机 GUID 上链接多个 JSON 对象这一繁琐的反人类工作。

有几个相互关联的 JSON 格式文件:

{
    "name": "some.interesting.name",
    "description": "helpful description",
    "instanceId": "random-GUID.for.some.interesting.name",
    "policies": [
        {
        "name": "some.interesting.name-policy",
        "instanceId": "random-GUID.for.some.interesting.name-policy"
        }
    ],
    "attributes": [
       "one": {
         "ref": "!some.interesting.name-2#random-GUID.for.some.interesting.name-2"
       }
    ]
}

名称是静态且可读的。 文件位置是静态的并遵循名称结构。

每当开发人员对任何文件进行最微小的更改时,InstanceId 都需要更改。 正在寻找一种工具,或者关于如何编写工具的想法,以随机生成 GUID 并将其插入到集合中每个文件的正确位置。

注意:我们已成功使用npm nanoid 生成 GUID,因此解决了随机值问题。

提供一个最小的可测试示例。 输入将是配置目录及其下的所有文件。

政策文件: 配置/策略/my_policy.js

{
   "name" : "policy.my_policy"
   "instanceId": "{$policy.my_policy}"
 
   "assets": [
       {  
         "user-info": "!assets.current_user_info#{$assets.current_user_info}"
       },
   ]

   "commands": [
      {
         "update-user": "!commands.update_admin_user#{$commands.update_admin_user}"
       }
   ]
}

配置/资产/current_user_info.js

{
   "name" : "assets.current_user_info"
   "instanceId": "{$assets.current_user_info}"
   "attribute": {
       "type": "string",
       "value": "admin"
   }
}

配置/命令/update_admin_user.js

{
   "name" : "commands.update_admin_user"
   "instanceId": "{$commands.update_admin_user}"
   
   "inputType": {
      "name": "assets.current_user_info"
      "instanceId": "{$assets.current_user_info}"
   }
 }
   

输出将是相同的文件,可能复制到输出目录,在相同的文件夹结构中, 变量在哪里

$assets.current_user_info
$commands.update_admin_user
$policy.my_policy 

使用 npm nanoid 或类似库生成的所有文件中的 GUID 值替换。

政策文件: 配置/策略/my_policy.js

{
   "name" : "policy.my_policy"
   "instanceId": "b35970fe-96dd-481d-a244-8880cc0cb818"
 
   "assets": [
       {  
         "user-info": "!assets.current_user_info#c3a17d65-921d-4cc4-9e23-5d40bd519289}"
       },
   ]

   "commands": [
      {
         "update-user": "!commands.update_admin_user#52a9a82e-a4e4-42f1-8376-a4e5ac06c9bd"
       }
   ]
}

配置/资产/current_user_info.js

{
   "name" : "assets.current_user_info"
   "instanceId": "c3a17d65-921d-4cc4-9e23-5d40bd519289"
   "attribute": {
       "type": "string",
       "value": "admin"
   }
}

配置/命令/update_admin_user.js

{
   "name" : "commands.update_admin_user"
   "instanceId": "52a9a82e-a4e4-42f1-8376-a4e5ac06c9bd"
   
   "inputType": {
      "name": "assets.current_user_info"
      "instanceId": "c3a17d65-921d-4cc4-9e23-5d40bd519289"
   }
 }
   

【问题讨论】:

    标签: javascript python json npm awk


    【解决方案1】:

    输入:

    $ cat vars2guids
    $assets.current_user_info       c3a17d65-921d-4cc4-9e23-5d40bd519289
    $commands.update_admin_user     52a9a82e-a4e4-42f1-8376-a4e5ac06c9bd
    $policy.my_policy               b35970fe-96dd-481d-a244-8880cc0cb818
    
    $ find configuration -type f -name '*.js'
    configuration/assets/current_user_info.js
    configuration/commands/update_admin_user.js
    configuration/policy/my_policy.js
    
    $ head -n 50 $(find configuration -type f -name '*.js')
    ==> configuration/assets/current_user_info.js <==
    {
       "name" : "assets.current_user_info"
       "instanceId": "{$assets.current_user_info}"
       "attribute": {
           "type": "string",
           "value": "admin"
       }
    }
    
    ==> configuration/commands/update_admin_user.js <==
    {
       "name" : "commands.update_admin_user"
       "instanceId": "{$commands.update_admin_user}"
    
       "inputType": {
          "name": "assets.current_user_info"
          "instanceId": "{$assets.current_user_info}"
       }
    }
    
    ==> configuration/policy/my_policy.js <==
    {
       "name" : "policy.my_policy"
       "instanceId": "{$policy.my_policy}"
    
       "assets": [
           {
             "user-info": "!assets.current_user_info#{$assets.current_user_info}"
           },
       ]
    
       "commands": [
          {
             "update-user": "!commands.update_admin_user#{$commands.update_admin_user}"
           }
       ]
    }
    

    工具:

    $ cat tst.sh
    #!/usr/bin/env bash
    
    tmp=$(mktemp) || exit 1
    while IFS= read -r file; do
    
        printf '\n###########\nUpdating %s\n' "$file" >&2
    
        awk '
            NR==FNR { v2g[$1]=$2; next }
            {
                for (var in v2g) {
                    if ( s=index($0,var) ) {
                        guid = v2g[var]
                        $0 = substr($0,1,s-1) guid substr($0,s+length(var))
                    }
                }
                print
            }
        ' vars2guids "$file" # > "$tmp" && mv -- "$tmp" "$file"
    
    done < <(find configuration -type f -name '*.js')
    

    输出:

    $ ./tst.sh
    
    ###########
    Updating configuration/assets/current_user_info.js
    {
       "name" : "assets.current_user_info"
       "instanceId": "{c3a17d65-921d-4cc4-9e23-5d40bd519289}"
       "attribute": {
           "type": "string",
           "value": "admin"
       }
    }
    
    ###########
    Updating configuration/commands/update_admin_user.js
    {
       "name" : "commands.update_admin_user"
       "instanceId": "{52a9a82e-a4e4-42f1-8376-a4e5ac06c9bd}"
    
       "inputType": {
          "name": "assets.current_user_info"
          "instanceId": "{c3a17d65-921d-4cc4-9e23-5d40bd519289}"
       }
    }
    
    ###########
    Updating configuration/policy/my_policy.js
    {
       "name" : "policy.my_policy"
       "instanceId": "{b35970fe-96dd-481d-a244-8880cc0cb818}"
    
       "assets": [
           {
             "user-info": "!assets.current_user_info#{c3a17d65-921d-4cc4-9e23-5d40bd519289}"
           },
       ]
    
       "commands": [
          {
             "update-user": "!commands.update_admin_user#{52a9a82e-a4e4-42f1-8376-a4e5ac06c9bd}"
           }
       ]
    }
    

    完成初始测试后,从# &gt; "$tmp" &amp;&amp; mv -- "$tmp" "$file" 中删除#,以便工具更新原始文件,而不是仅打印到标准输出。

    要创建vars2guids 文件,方法是为 .js 文件中的每个变量生成一个 guid,并假设变量在 {...} 中总是看起来像 $word-chars.word-chars,而其他看起来都不是这样:

    vars=( $(find configuration -type f -name '*.js' -exec awk '
        {
            while ( match($0,/\{\$[[:alnum:]_]+\.[[:alnum:]_]+}/) ) {
                print substr($0,RSTART+1,RLENGTH-2)
                $0 = substr($0,RSTART+RLENGTH)
            }
        }
    ' {} + | sort -u) )
    
    for var in "${vars[@]}"; do
        guid=$(echo "$RANDOM")
        printf '%s\t%s\n' "$var" "$guid"
    done # > vars2guids
    

    上面会输出:

    $assets.current_user_info       29283
    $commands.update_admin_user     28057
    $policy.my_policy       1187
    

    echo "$RANDOM" 更改为您运行以生成 GUID 的任何命令。取消注释 # &gt; vars2guids 使其将输出写入 vars2guids 而不是 stdout。

    所以在完成所有测试之后,您的脚本可能如下所示:

    $ cat tst.sh
    #!/usr/bin/env bash
    
    tmp=$(mktemp) || exit 1
    
    vars=( $(find configuration -type f -name '*.js' -exec awk '
        {
            while ( match($0,/\{\$[[:alnum:]_]+\.[[:alnum:]_]+}/) ) {
                print substr($0,RSTART+1,RLENGTH-2)
                $0 = substr($0,RSTART+RLENGTH)
            }
        }
    ' {} + | sort -u) )
    
    for var in "${vars[@]}"; do
        guid=$(echo "$RANDOM")
        printf '%s\t%s\n' "$var" "$guid"
    done > vars2guids
    
    while IFS= read -r file; do
    
        printf '\n###########\nUpdating %s\n' "$file" >&2
    
        awk '
            NR==FNR { v2g[$1]=$2; next }
            {
                for (var in v2g) {
                    if ( s=index($0,var) ) {
                        guid = v2g[var]
                        $0 = substr($0,1,s-1) guid substr($0,s+length(var))
                    }
                }
                print
            }
        ' vars2guids "$file" > "$tmp" && mv -- "$tmp" "$file"
    
    done < <(find configuration -type f -name '*.js')
    

    【讨论】:

    • 花了一些时间弄清楚如何读取该片段中的查找输出...构建了一个 python 脚本来执行此操作,似乎更简单。感谢您的帮助!你的脚本很有帮助。
    【解决方案2】:

    这是一个 Python 脚本,它使用 uuid.uuid4() 为 instanceIds 生成 GUID 并填充所有文件中的值。文件从 src/ 复制到 output/,具有相同的目录结构。 使用python3。

    # Import the os module, for the os.walk function
    import os
    import re
    import uuid
    
    # Set the directory you want to start from
    rootDir = 'src'
    outputDir = 'output'
    
    pattern = re.compile("{\$((\w*\.)*(\w)*)}")
    instanceId = set([])
    
    def findInstanceIdName(fileName):
        # print("Looking for instanceIds in " + fileName);
        found = [];
        for i, line in enumerate(open(fileName)):
            for match in re.finditer(pattern, line):
                found_match = match.group();
                found.append(found_match);
        return found;
    
    def generateInstanceIdValue(nameList):
        values = {}
        for instanceName in nameList:
            values[instanceName] = str(uuid.uuid4());
        return values;
    
    def processFile(inputFileName, outputFileName, instanceIdValues):
        with open(inputFileName, "r") as inputFile, open(outputFileName, "w") as outputFile:
            line = inputFile.read();
            # print("Found line: <" + line + ">");
            for key in instanceIdValues.keys():
                line = line.replace(key, instanceIdValues[key]);
            outputFile.write(line);
    
    
    for dirName, subdirList, fileList in os.walk(rootDir):
        # print('Found directory: %s' % dirName)
        for fname in fileList:
            fullFileName = dirName + "/" + fname;
            instanceId.update(findInstanceIdName(fullFileName));
    
    instanceIdValues = generateInstanceIdValue(instanceId);
    #print(instanceIdValues);
    
    for dirName, subdirList, fileList in os.walk(rootDir):
        for fname in fileList:
            outputDirName = outputDir + dirName[len(rootDir):];
            os.makedirs(outputDirName, exist_ok=True);
            fullFileName = dirName + "/" + fname;
            outputFileName = outputDir + fullFileName[len(rootDir):];
            processFile(fullFileName, outputFileName, instanceIdValues);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-21
      • 1970-01-01
      • 2015-10-05
      • 1970-01-01
      • 2011-03-11
      相关资源
      最近更新 更多