使用bq中管道分隔的键和值使用jq创建JSON

使用bq中管道分隔的键和值使用jq创建JSON,第1张

使用bq中管道分隔的键和值使用jq创建JSON 先决条件

对于以下所有内容,假定您的内容位于名为的shell变量中

s

s='ConTAINER|CPU%|MEMUSAGE/LIMIT|MEM%|NETI/O|BLOCKI/O|PIDSnginx_container|0.02%|25.09MiB/15.26GiB|0.16%|0B/0B|22.09MB/4.096kB|0'
什么(现代jq)
# thanks to @JeffMercado and @chepner for refinements, see commentsjq -Rn '( input  | split("|") ) as $keys |( inputs | split("|") ) as $vals |[[$keys, $vals] | transpose[] | {key:.[0],value:.[1]}] | from_entries' <<<"$s"
如何(现代jq)

这需要非常新的(可能是1.5?)

jq
才能工作,并且是一堆密集的代码。分解:

  • using
    -n
    阻止
    jq
    自己读取stdin,而让
    input
    and 可以读取整个输入流
    inputs
    -前者读取一行,而后者读取所有其余行。(
    -R
    ,对于原始输入,导致读取文本行而不是JSON对象)。
  • 使用
    [$keys, $vals] | transpose[]
    ,我们生成了
    [key, value]
    对(以Python的术语来说,将两个列表压缩在一起)。
  • 使用
    {key:.[0],value:.[1]}
    ,我们将每一
    [key, value]
    对变成以下形式的对象
    {"key": key, "value": value}
  • 使用
    from_entries
    ,我们将这些对组合为包含这些键和值的对象。

什么(Shell assisted)

jq
将比上述版本更旧,并且在本地
jq
解决方案可能更难以解决的情况下是一种易于采用的方法:

{   IFS='|' read -r -a keys # read first line into an array of strings   ## read each subsequent line into an array named "values"   while IFS='|' read -r -a values; do    # setup: positional arguments to pass in literal variables, query with pre        jq_args=( )    jq_query='.'    # copy values into the arguments, reference them from the generated pre        for idx in "${!values[@]}"; do        [[ ${keys[$idx]} ]] || continue # skip values with no corresponding key        jq_args+=( --arg "key$idx"   "${keys[$idx]}"   )        jq_args+=( --arg "value$idx" "${values[$idx]}" )        jq_query+=" | .[$key${idx}]=$value${idx}"    done    # run the generated command    jq "${jq_args[@]}" "$jq_query" <<<'{}'  done} <<<"$s"

如何(Shell assisted)

jq
上面调用的命令类似于:

jq --arg key0   'CONTAINER'    --arg value0 'nginx_container'    --arg key1   'CPU%'    --arg value1 '0.0.2%'    --arg key2   'MEMUSAGE/LIMIT'    --arg value2 '25.09MiB/15.26GiB'    '. | .[$key0]=$value0 | .[$key1]=$value1 | .[$key2]=$value2'    <<<'{}'

…将每个键和值带外传递(这样就将其视为文字字符串而不是解析为JSON),然后分别引用它们。


结果

以上任何一种都会发出:

{  "CONTAINER": "nginx_container",  "CPU%": "0.02%",  "MEMUSAGE/LIMIT": "25.09MiB/15.26GiB",  "MEM%": "0.16%",  "NETI/O": "0B/0B",  "BLOCKI/O": "22.09MB/4.096kB",  "PIDS": "0"}

为什么

简而言之: 因为可以保证生成有效的JSON作为output

考虑以下示例,该示例将打破更多幼稚的方法:

s='key ending in a backslashvalue "with quotes"'

当然,这些是意外情况,但是

jq
知道如何处理它们:

{  "key ending in a backslash\": "value "with quotes""}

…而一个不理解JSON字符串的实现很容易最终发出:

{  "key ending in a backslash": "value "with quotes""}


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/4901060.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-12
下一篇 2022-11-12

发表评论

登录后才能评论

评论列表(0条)

保存