使用 JSON 输入在 bash 中创建 Select 菜单
Creating a Select Menu in bash using JSON input
我正在尝试使用 bash 中的 select 函数创建菜单。我正在访问 API,它将 return 以 json 格式输出。然后,我会将 API return 的内容处理成一个 select 语句,用户可以在其中进行交互。
这是 API 调用以及我如何解析输出:
curl -H "Authorization:Bearer $ACCESS_TOKEN" https://api.runscope.com/buckets \
| python -mjson.tool > output.json
这会将 curl 的输出通过 python 的 json 解析工具发送到 output.json 文件中。
然后我使用这个 json blob 创建一个数组。我必须将 IFS 设置为 \n 才能正确解析文件:
IFS=$'\n'
BUCKETS=("$(jq '.data | .[].name' output.json)")
然后我向数组添加一个退出选项,以便用户可以退出 selection 菜单:
BUCKETS+=("Exit")
最后,我创建了菜单:
select BUCKET in $BUCKETS;
do
case $BUCKET in
"Exit")
echo "Exiting..."
break;;
esac
echo "You picked: $BUCKET"
done
不幸的是,这不会创建退出选项。我能够看到一个菜单,其中包含我想要的所有其他选项,但退出选项除外。菜单和数组中的每个选项都有引号。如何让退出选项显示出来?
而不是
jq '.data | .[].name' output.json
尝试
jq -r '.data | .[].name' output.json
(-r
: 没有引号的原始数据)
最重要的部分:
select BUCKET in "${BUCKETS[@]}"
^^^
ARRAY syntax
$BUCKETS
正在扩展到 BUCKETS
数组的 first 元素。
然后将其分词并用作您的 select 条目。
这是有道理的,因为您将 jq
子外壳用双引号括起来,这样可以防止在那里发生分词(这意味着 IFS
更改没有做任何我认为的事情)。
Iff 您的条目可以包含空格 and 您希望将其正确分配给数组,方法是读取输出jq
的 while IFS= read -r entry; do
循环。
BUCKETS=()
while IFS= read -r entry; do
BUCKETS+=("$entry")
done < <(jq '.data | .[].name' output.json)
然后将退出项附加到数组。
BUCKETS+=(Exit)
然后使用
select BUCKET in "${BUCKETS[@]}"; do
(select a in l; do
或 select a in l\ndo
都不需要 ;
和 \n
。)
综上所述,除非您需要 output.json
做其他事情,否则您也可以避免这种情况。
BUCKETS=()
while IFS= read -r entry; do
BUCKETS+=("$entry")
done < <(curl -H "Authorization:Bearer $ACCESS_TOKEN" https://api.runscope.com/buckets | python -mjson.tool | jq '.data | .[].name')
我正在尝试使用 bash 中的 select 函数创建菜单。我正在访问 API,它将 return 以 json 格式输出。然后,我会将 API return 的内容处理成一个 select 语句,用户可以在其中进行交互。
这是 API 调用以及我如何解析输出:
curl -H "Authorization:Bearer $ACCESS_TOKEN" https://api.runscope.com/buckets \
| python -mjson.tool > output.json
这会将 curl 的输出通过 python 的 json 解析工具发送到 output.json 文件中。
然后我使用这个 json blob 创建一个数组。我必须将 IFS 设置为 \n 才能正确解析文件:
IFS=$'\n'
BUCKETS=("$(jq '.data | .[].name' output.json)")
然后我向数组添加一个退出选项,以便用户可以退出 selection 菜单:
BUCKETS+=("Exit")
最后,我创建了菜单:
select BUCKET in $BUCKETS;
do
case $BUCKET in
"Exit")
echo "Exiting..."
break;;
esac
echo "You picked: $BUCKET"
done
不幸的是,这不会创建退出选项。我能够看到一个菜单,其中包含我想要的所有其他选项,但退出选项除外。菜单和数组中的每个选项都有引号。如何让退出选项显示出来?
而不是
jq '.data | .[].name' output.json
尝试
jq -r '.data | .[].name' output.json
(-r
: 没有引号的原始数据)
最重要的部分:
select BUCKET in "${BUCKETS[@]}"
^^^
ARRAY syntax
$BUCKETS
正在扩展到 BUCKETS
数组的 first 元素。
然后将其分词并用作您的 select 条目。
这是有道理的,因为您将 jq
子外壳用双引号括起来,这样可以防止在那里发生分词(这意味着 IFS
更改没有做任何我认为的事情)。
Iff 您的条目可以包含空格 and 您希望将其正确分配给数组,方法是读取输出jq
的 while IFS= read -r entry; do
循环。
BUCKETS=()
while IFS= read -r entry; do
BUCKETS+=("$entry")
done < <(jq '.data | .[].name' output.json)
然后将退出项附加到数组。
BUCKETS+=(Exit)
然后使用
select BUCKET in "${BUCKETS[@]}"; do
(select a in l; do
或 select a in l\ndo
都不需要 ;
和 \n
。)
综上所述,除非您需要 output.json
做其他事情,否则您也可以避免这种情况。
BUCKETS=()
while IFS= read -r entry; do
BUCKETS+=("$entry")
done < <(curl -H "Authorization:Bearer $ACCESS_TOKEN" https://api.runscope.com/buckets | python -mjson.tool | jq '.data | .[].name')