将 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"
我今天第一次和 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"