You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用bash、sed、grep或awk从无效JSON中提取指定字段?

问题排查

你的脚本运行异常有三个核心原因:

  1. for循环拆分规则问题:bash的for in循环默认按照IFS(内部字段分隔符,默认包含空格、制表符、换行符)分割输入内容,你的每条条目里有大量空格,所以会被拆成一个个小片段,而不是按行拆分。按行读取应该用while IFS= read -r结构。
  2. 变量赋值语法错误:你写的component=echo $each | awk ...是错误语法,捕获命令输出需要用$()包裹,正确写法是component=$(echo $each | awk ...)。
  3. jq报错原因:一是该内容本身不符合JSON规范(键没有双引号、字符串值没有双引号、外层没有数组包裹),二是$x没有用双引号包裹,被shell按空格拆分后传给jq的内容是截断的。

解决方案1:转成合法JSON后用jq解析(推荐)

用sed先补全JSON的缺失格式,就可以直接用jq处理:

# 补全JSON格式后直接输出结果
echo "[$x]" | sed -E 's/([a-zA-Z0-9]+): /"\1": /g' | sed -E 's/: ([^0-9n][^,}]*)/: "\1"/g' | jq '.[] | select(.componentId | startswith("00N") | not) | {componentName, referenceName}'

如果需要遍历处理提取到的值,可以用以下写法:

echo "[$x]" | sed -E 's/([a-zA-Z0-9]+): /"\1": /g' | sed -E 's/: ([^0-9n][^,}]*)/: "\1"/g' | jq -c '.[] | select(.componentId | startswith("00N") | not)' | while IFS= read -r entry; do
    component=$(echo "$entry" | jq -r '.componentName')
    reference=$(echo "$entry" | jq -r '.referenceName')
    echo "component: $component"
    echo "reference: $reference"
done

解决方案2:直接用awk匹配提取

如果环境受限无法使用jq,直接用awk按规则拆分提取即可:

echo "$x" | awk -v RS='}, {' '
{
    match($0, /componentId: ([^,]+),/, id)
    if (id[1] !~ /^00N/) {
        match($0, /componentName: ([^,]+),/, comp)
        match($0, /referenceName: ([^,]+),/, ref)
        print "component: " comp[1]
        print "reference: " ref[1]
    }
}'

这个方法直接用}, {作为条目分隔符,不需要处理JSON格式,更轻量。

内容的提问来源于stack exchange,提问作者Patlatus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 14:36:05