【问题标题】:jq "Invalid numeric literal"jq“无效的数字文字”
【发布时间】:2018-08-02 23:26:04
【问题描述】:

我正在尝试使用 jq 将 df -i 命令的输出解析为 json 模板,但在将数组中的数值读入 json 模板时收到以下错误:

parse error: Invalid numeric literal at line 10, column 31

这是脚本:

#!/bin/sh

JSON=`cat inode-template.json`

#get number of rows in output
numLines=`df -ih | wc -l`

#row iterator (start at 2 to skip the header row)
for ((row=2; row<=$numLines; row++))
do
  arrCounter=0 #array counter reset
  #for each value in col (minus 'mounted on'):
  for ((val=1; val<=5; val++))
  do
    value=$(df -iP | awk -v value=$val 'NR=='$row'{sub( "%", "", $value); print $value }') #get each value
    tempArr[$arrCounter]=$value #store row value
    arrCounter=$((arrCounter + 1))
  done
  echo "${tempArr[@]}"
  #Assign values in json template
  JSON=$(jq -c --arg filesys "${tempArr[0]}" --arg iTotal ${tempArr[1]} --arg iUsed ${tempArr[2]} --arg iFree ${tempArr[3]} --arg iPercent ${tempArr[4]} '.metrics[].fileSystem |= $filesys | .metrics[].InodesTotal |= $iTotal | .metrics[].InodesUsed |= $iUsed | .metrics[].InodesFree |= $iFree | .metrics[].InodeUsedPercent |= $iPercent' inode-template.json)

  echo "${JSON}"
  tempArr=() #reset array
done

这是正在读取的 json 模板:

{
  "name": "inodeparse",
  "metrics": [
    {
      "event_type": "test",
      "provider": "test",
      "fileSystem": "FILESYS",
      "InodesTotal":NODESTOTAL,
      "InodesUsed":NODESUSED,
      "InodesFree":NODESFREE,
      "InodeUsedPercent":NODESPERCENT
    }
  ]
}

在使用 jq 替换模板中的值之前,是否有任何选项可以将数组项声明为整数?

【问题讨论】:

    标签: json templates jq inode


    【解决方案1】:

    您的问题的简短回答是: (1) 您将不得不采用稍微不同的方法,因为“模板”文件既不是有效的 JSON,也不是有效的 jq 程序 (2)使用--argjson而不是--arg,至少对于数字(如果你的jq不支持--argjson,它已经很旧了-肯定是时候升级了:0)

    jq Cookbook 有一节描述了使用 jq 进行模板化的两种简单方法。如果可能的话,使用其中一种方法会更好。

    以下说明了使用您的模板的“$-variables”方法,修改后模板变量为 jq "$-variables":

    $ cat inode-template.jq
    {
      "name": "inodeparse",
      "metrics": [
        {
          "event_type": "test",
          "provider": "test",
          "fileSystem": "FILESYS",
          "InodesTotal": $NODESTOTAL,
          "InodesUsed": $NODESUSED,
          "InodesFree": $NODESFREE,
          "InodeUsedPercent": $NODESPERCENT
        }
      ]
    }
    

    现在我们可以使用 jq 的 --argjson 命令行选项来实例化模板:

    $ jq -n --argjson NODESTOTAL 1 --argjson NODESUSED 2 --argjson NODESFREE 3 --argjson NODESPERCENT 4 -f inode-template.jq
    {
      "name": "inodeparse",
      "metrics": [
        {
          "event_type": "test",
          "provider": "test",
          "fileSystem": "FILESYS",
          "InodesTotal": 1,
          "InodesUsed": 2,
          "InodesFree": 3,
          "InodeUsedPercent": 4
        }
      ]
    }
    

    另一种方法也很好。

    当然,您也可以使用字段分配方法。事实上,这三种方法都是相互兼容的。

    【讨论】:

    • 谢谢!这种方法适用于数值,但是当添加 $FILESYS 作为变量并传递字符串时,我收到"jq: invalid JSON text passed to --argjson" /// 我的 json 模板也是有效的,我可以将数组变量作为字符串读取,但我想要以整数形式插入的总数/已用/空闲/百分比。
    • 在您的模板中,FILESYS 作为字符串给出。您可以将其更改为“$FILESYS”并使用--arg FILESYS“$FILESYS”。 (如果对字符串使用 --argjson,则必须确保它们是 JSON 字符串,即包含引号。)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多