将 jq 与来自 shell 脚本的未知数量的参数一起使用?

Using jq with an unknown amount of arguments from shell script?

我今天第一次和 jq 一起工作,我快要失去理智了。我已经尝试过各种肮脏的方法来以某种方式使这项工作正常进行。让我们言归正传:

我正在尝试为某些用例进一步开发用于 Unifi 控制器的漂亮准系统 API: https://dl.ui.com/unifi/6.0.41/unifi_sh_api

这是一些模拟数据(真正的 json 数据是数千行):

{
  "meta": {
    "rc": "ok"
  },
  "data": [
    {
      "_id": "61a0da77f730e404af0edc3c",
      "ip": "10.19.31.120",
      "mac": "ff:ec:ff:89:ff:58",
      "name": "Test-Accesspoint"
    }
  ]
}

这是我的 advancedapi.sh

#!/bin/bash
source unifiapi.sh
unifi_login 1>dev/null

if [ "" ];
then
command=
shift
else
echo "Please enter command"
exit
fi
#jq -r '.data[] | "\(.name),\(.mac)"'

assembleKeys(){
c="0"
seperator=";"
keys=$(for i in "$@"
do
        c=$(expr $c + 1)
        if [ $c -gt 1 ];
        then
                echo -n "${seperator}\(.${i})"
        else
                echo -n "\(.${i})"
        fi
done
echo)
}

assembleJQ(){
c=0
jq=$(echo -en 'jq -r -j \x27.data[] | '
for i in "$@"
do
        if [ "$c" != "0" ];
        then
        echo -en ",\x22 \x22,"
        fi
c=1
echo -en ".$i"
done
echo -en ",\x22\\n\x22\x27")
echo "$jq"
}


getDeviceKeys(){
assembleJQ "$@"



#unifi_list_devices | jq -r '.data[]' | jq -r "${keys}"
#export keys=mac
#export second=name
#unifi_list_devices | jq -r -j --arg KEYS "$keys" --arg SECOND "$second" '.data[] | .[$KEYS]," ",.[$SECOND],"\n"'

unifi_list_devices | $jq
#unifi_list_devices | jq -r -j '.data[] | .mac," ",.name,"\n"'
}

"$command" $@

用户应该能够使用任意数量的参数调用 API 中的任何函数。 所以基本上是这样的:

#export keys=mac
#export second=name
#unifi_list_devices | jq -r -j --arg KEYS "$keys" --arg SECOND "$second" '.data[] | .[$KEYS]," ",.[$SECOND],"\n"'

有效,但参数数量有限。我想将 $@ 传递给 jq。

我正在尝试获取设备的名称和 mac-地址,方法是调用:

./advancedapi.sh getDeviceKeys mac name

这应该 return 设备的 mac 地址和名称。但它只给我这个:

jq -r -j '.data[] | .mac," ",.name,"\n"'
jq: error: syntax error, unexpected INVALID_CHARACTER, expecting $end (Unix shell quoting issues?) at <top-level>, line 1:
'.data[]
jq: 1 compile error

最上面一行是 jq 命令,手动调用时它工作得很好。

assembleKeys 函数是我尝试生成如下所示的字符串:

jq -r '.data[] | "\(.name),\(.mac)"'

任何人都可以向我解释,最好是深入的,如何做到这一点?我要疯了!

谢谢!

json 中有错误(红色突出显示的逗号)(不需要逗号)


$
$ cat j.json | jq -r '.data[] | "\(.name)█\(.mac)█\(.ip)█\(._id)"'
Test-Accesspoint█ff:ec:ff:89:ff:58█10.19.31.120█61a0da77f730e404af0edc3c
$ cat j.json
{
  "meta": {
    "rc": "ok"
  },
  "data": [
    {
      "_id": "61a0da77f730e404af0edc3c",
      "ip": "10.19.31.120",
      "mac": "ff:ec:ff:89:ff:58",
      "name": "Test-Accesspoint"
    }
  ]
}
$

如果 api 已经给了这个 json 你应该编辑它,然后将它传送到 jq [也许用 sed 或类似的东西]

I want to pass $@ to jq.

实际上有很多方法可以做到这一点,但最简单的可能是使用 --args command-line 选项,如下所示:

文件:检查

#/bin/bash
echo "${@}"
jq -n '$ARGS.positional' --args "${@}" 

示例运行:

./check 1 2 3
1 2 3
[
  "1",
  "2",
  "3"
]

投影

这里有一个示例,可能更接近您要查找的内容。 使用您的样本 JSON:

文件:check2

#/bin/bash
jq -r '
  def project($array):
    . as $in | reduce $array[] as $k ([]; . + [$in[$k]]);
  $ARGS.positional,
  (.data[] | project($ARGS.positional))
  | @csv
' input.json --args "${@}" 
./check2 name mac
"name","mac"
"Test-Accesspoint","ff:ec:ff:89:ff:58"