程序问答   发布时间:2022-06-01  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了从bash中的管道分隔键和值中使用jq创建JSON大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决从bash中的管道分隔键和值中使用jq创建JSON?

开发过程中遇到从bash中的管道分隔键和值中使用jq创建JSON的问题如何解决?下面主要结合日常开发的经验,给出你关于从bash中的管道分隔键和值中使用jq创建JSON的解决方法建议,希望对你解决从bash中的管道分隔键和值中使用jq创建JSON有所启发或帮助;

先决条件

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

s='CONTAINER|cpu%|MEMUSAGE/liMIT|MEM%|NETI/O|BLOCKI/O|PIDS
Nginx_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 comments
jq -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,而让inputand 可以读取整个输入流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 code    
    jq_args=( )
    jq_query='.'

    # copy values into the arguments, reference them from the generated code    
    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 BACkslash\
value "with quotes"'

当然,这些是意外情况,但是jq知道如何处理它们:

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

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

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

解决方法

我试图从bash中的字符串创建一个json对象。字符串如下。

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

输出来自docker stats命令,我的最终目标是将自定义指标发布到AWS CloudWatch。我想将此字符串格式化为json。

{
    "CONTAINER":"nginx_container","CPU%":"0.02%",....
}

我以前使用过jq命令,似乎在这种情况下应该可以正常工作,但是我还没有能够提出一个好的解决方案。除了使用sed或awk对变量名进行硬编码和索引编制以外。然后从头开始创建一个json。任何建议,将不胜感激。谢谢。

大佬总结

以上是大佬教程为你收集整理的从bash中的管道分隔键和值中使用jq创建JSON全部内容,希望文章能够帮你解决从bash中的管道分隔键和值中使用jq创建JSON所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: