栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

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

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

从bash中的管道分隔键和值中使用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
    ,我们将这些对组合到包含这些键和值的对象中。

什么(贝壳辅助)

这将在

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"

如何(壳辅助)

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""}


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/449236.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号