【问题标题】:JSON to table formatting (got it from - http://json2table.com)JSON 到表格格式(从 - http://json2table.com 获得)
【发布时间】:2020-10-23 07:41:38
【问题描述】:

我目前正在尝试将 AWS ECR 扫描集成到我们的 CI/CD 管道中,并将结果以人类可读的形式传递给我们的工程师。

命令 - aws ecr describe-image-scan-findings --repository-name ${REPNAME} --image-id imageTag=latest --profile ${PROFILE} --region ${REGION}

返回类似于以下 [redacted] 输出的内容 -

    "imageScanFindings": {
        "findings": [
            {
                "name": "CVE-2018-12886",
                "description": "stack_protect_prologue in cfgexpand.c and stack_protect_epilogue in function.c in GNU Compiler Collection (GCC) 4.1 through 8 (under certain circumstances) generate instruction sequences when targeting ARM targets that spill the address of the stack protector guard, which allows an attacker to bypass the protection of -fstack-protector, -fstack-protector-all, -fstack-protector-strong, and -fstack-protector-explicit against stack overflow by controlling what the stack canary is compared against.",
                "uri": "https://security-tracker.debian.org/tracker/CVE-2018-12886",
                "severity": "MEDIUM",
                "attributes": [
                    {
                        "key": "package_version",
                        "value": "8.3.0-6"
                    },
                    {
                        "key": "package_name",
                        "value": "gcc-8"
                    },
                    {
                        "key": "CVSS2_VECTOR",
                        "value": "AV:N/AC:M/Au:N/C:P/I:P/A:P"
                    },
                    {
                        "key": "CVSS2_SCORE",
                        "value": "6.8"
                    }
                ]
            },
            {
                "name": "CVE-2020-1751",
                "description": "An out-of-bounds write vulnerability was found in glibc before 2.31 when handling signal trampolines on PowerPC. Specifically, the backtrace function did not properly check the array bounds when storing the frame address, resulting in a denial of service or potential code execution. The highest threat from this vulnerability is to system availability.",
                "uri": "https://security-tracker.debian.org/tracker/CVE-2020-1751",
                "severity": "MEDIUM",
                "attributes": [
                    {
                        "key": "package_version",
                        "value": "2.28-10"
                    },
                    {
                        "key": "package_name",
                        "value": "glibc"
                    },
                    {
                        "key": "CVSS2_VECTOR",
                        "value": "AV:L/AC:M/Au:N/C:P/I:P/A:C"
                    },
                    {
                        "key": "CVSS2_SCORE",
                        "value": "5.9"
                    }
                ]
            },
            {
                "name": "CVE-2019-20367",
                "description": "nlist.c in libbsd before 0.10.0 has an out-of-bounds read during a comparison for a symbol name from the string table (strtab).",
                "uri": "https://security-tracker.debian.org/tracker/CVE-2019-20367",
                "severity": "MEDIUM",
                "attributes": [
                    {
                        "key": "package_version",
                        "value": "0.9.1-2"
                    },
                    {
                        "key": "package_name",
                        "value": "libbsd"
                    },
                    {
                        "key": "CVSS2_VECTOR",
                        "value": "AV:N/AC:L/Au:N/C:P/I:N/A:P"
                    },
                    {
                        "key": "CVSS2_SCORE",
                        "value": "6.4"
                    }
                ]
            },
            {
                "name": "CVE-2019-12904",
                "description": "In Libgcrypt 1.8.4, the C implementation of AES is vulnerable to a flush-and-reload side-channel attack because physical addresses are available to other processes. (The C implementation is used on platforms where an assembly-language implementation is unavailable.)",
                "uri": "https://security-tracker.debian.org/tracker/CVE-2019-12904",
                "severity": "MEDIUM",
                "attributes": [
                    {
                        "key": "package_version",
                        "value": "1.8.4-5"
                    },
                    {
                        "key": "package_name",
                        "value": "libgcrypt20"
                    },
                    {
                        "key": "CVSS2_VECTOR",
                        "value": "AV:N/AC:M/Au:N/C:P/I:N/A:N"
                    },
                    {
                        "key": "CVSS2_SCORE",
                        "value": "4.3"
                    }
                ]
            }
        ],
        "imageScanCompletedAt": "2020-10-23T00:03:10+05:30",
        "vulnerabilitySourceUpdatedAt": "2020-10-22T16:21:44+05:30",
        "findingSeverityCounts": {
            "MEDIUM": 14,
            "INFORMATIONAL": 72,
            "LOW": 18,
            "UNDEFINED": 3
        }
    },
    "registryId": "12345678911",
    "repositoryName": "name-of-repo",
    "imageId": {
        "imageDigest": "sha256:1213412412412451241414214141412412",
        "imageTag": "latest"
    },
    "imageScanStatus": {
        "status": "COMPLETE",
        "description": "The scan was completed successfully."
    }
}

上面的内容不适合人类阅读,特别是如果有很多发现并且 JSON 输出有数百行。

我想将上述输出转换为更“人类”可读的形式,而不会省略任何返回的信息。我尝试为AWS CLI 使用--output table 选项,但它在列和行之间包含很多空格。

我尝试使用jq 将其转换为表格或使用map 的某种.tsv,但没有运气,因为我是JQ 的初学者。如果有人对如何解决这个问题有任何想法 - 任何帮助将不胜感激。

我的目标是从http://json2table.com/ 获得以下内容-

Expected Formatted Output

【问题讨论】:

  • 使用jq 发布您的尝试并发布预期的表格输出格式
  • 在样例的开头放一个大括号以便格式化
  • 在许多不同的脚本语言中有大量的json2tablejson2html 转换器。也许其中之一就足够了?

标签: json formatting jq aws-cli amazon-ecr


【解决方案1】:

下面根据我的生成一个带有嵌套子表的表 了解基本要求。

示例

为了说明 json2tree 的主要功能是做什么的,这里有一个例子:

输入:

[
  {"a": 1,"b": 2,"ary":[{"c":0,"d":1},{"c":10,"d":11}],"another":[{"a":1,"b":2}]},
  {"a":10,"b":20,"c":30,"ary":[{"e":0,"f":1},{"g":10,"h":11}],"xyzzy":"x"}
 ] 

输出(未制表):

a       b       ary                             another         c       xyzzy
1       2       c       d                       a       b       null    null
                0       1                       1       2               
                10      11                                              
10      20      e       f       g       h                       30      x
                0       1       null    null                            
                null    null    10      11                              
            

假设

除了错误,关于输入数据的唯一假设如下:

  1. 输入是一个 JSON 对象数组,$a;
  2. 如果 $a[$i][$k] 是某个 $i 和某个键 $k 的 JSON 对象数组, 那么 $a[$j][$k] 是所有 $j 的 JSON 对象数组

稳健性

实现的复杂性(或至少是长度)是其相对于输入数据相当健壮的结果。例如,不要求顶级对象具有相同的键,或者以一致的顺序指定它们。

然而,这种健壮性是以tostring 为代价来实现的 JSON 实体存在于上述 (2) 未设想的上下文中。

辅助函数

# determine if the input is an array of JSON objects
def is_array_of_objects: type=="array" and all(.[]; type=="object");

# input: a JSON object
def reorder_keys($object): . as $in | $object | with_entries(.value = $in[.key]);

# input: an array of one or more objects
# output: an array of similar objects but altered by adding null values so that they all have the same keys,
#         and so that the keys are in the same order
def synthesize:
  (add|map_values(null)) as $a
  | map($a + .)
  | .[0] as $template
  | map(reorder_keys($template));

# Input: an array of conformal objects, i.e., with the same keys,
#        and such that if .[$i][$k] is an array of objects for any $i or $i, then .[$j][$k] is 
#        also an array of objects for all $j
# Output: an object with the same keys but with the value replaced by the max `length` for an array of objects,
#        and -1 otherwise.
def object_of_widths:
  def w: map_values(if is_array_of_objects then .[0]|length else -1 end);
  def keywise_maximum($x; $y): reduce ($y|keys_unsorted)[] as $k ({}; .[$k] = ([$x[$k],$y[$k]]|max));
  reduce (.[]|w) as $w ({}; keywise_maximum(.; $w));

主程序

# Input: an array of objects
# Output: a table that treats top-level arrays of JSON objects specially
def json2tree:

  # input: an array
  # output: an array of length at least $n
  def rpad($n): . + [range(0;$n-length)|null];
  
  # input: an object
  def print_first_line($keys; $widths):
    [$keys[] as $k | $k, (if $widths[$k] == -1 then empty else range(1;$widths[$k]) | null end)];
    
  # input: an object
  def print_second_line($keys; $widths):
    [$keys[] as $k
    | if $widths[$k] == -1
      then .[$k]|tostring
      elif .[$k] then .[$k][0]|keys_unsorted|rpad($widths[$k])[]
      else range(0; $widths[$k]) | null
      end];

  # input: an object
  # $i - the $i-th object in the array
  def print_nth_line($i; $keys; $widths):
    [$keys[] as $k
    | if $widths[$k] == -1
      then null
      elif $i < (.[$k]|length)
      then (.[$k][$i] | map(tostring) | rpad($widths[$k]))[]
      else (range(0;$widths[$k])|null)
      end] ;

  synthesize
  | map(map_values(if is_array_of_objects then synthesize else . end))
  | (.[0] | keys_unsorted) as $keys
  | object_of_widths as $widths
  | (.[0] | print_first_line($keys; $widths)),
    (range(0; length) as $ix
     | (.[$ix] | print_second_line($keys; $widths)),
       (.[$ix]
        | ([.[] | if is_array_of_objects then length else 0 end] | max) as $mx
        | range(0; $mx) as $i | print_nth_line($i; $keys; $widths) ) ) ;

json2tree | @tsv

【讨论】:

    猜你喜欢
    • 2022-07-15
    • 2018-07-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-19
    相关资源
    最近更新 更多