首页 > 解决方案 > 改进`jq | @base64` 速度

问题描述

注意:这是一个大型脚本的简化版本。

真正的脚本递归地搜索要 ssh 到的服务器,每个.g[](组)可以包含更多groups,最终将包含一个.s(服务器)对象,该对象包含 IP/名称/用户/等...

在显示第一组(花费太长时间)后,系统会询问用户他想“进入”哪个组或他想连接到哪个服务器。(为了简化省略了服务器)


考虑以下 JSON 文件;

{
    "g": [
        {
            "id": "1",
            "name": "Group - 1"
        },
        {
            "id": "2",
            "name": "Group - 2"
        },
        ...
        {
            "id": "10",
            "name": "Group - 10"
        }
    ]
}

使用,我向用户展示了.g[]数组中出现的每个“选项”。

基于这篇文章,我正在使用以下内容for-loop来迭代“选项”;

for row in $(jq -r '.g[] | @base64' <<< $raw); do
    echo -e "${prefix}    $(_jq $row '.id')${hk}  $(_jq $row '.name')"
done


问题:脚本需要〜0.6几秒钟才能显示前 10 个条目;

$ time ./script
./script  0.61s user 0.09s system 101% cpu 0.685 total

问题:如何提高脚本的速度?


一些失败的尝试;


#!/bin/bash
set -e

# Statics
_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )/"
red=`tput setaf 1`; green=`tput setaf 2`; yellow=`tput setaf 3`; blue=`tput setaf 4`; magenta=`tput setaf 5`; cyan=`tput setaf 6`; bow=`tput setaf 0;tput setab 7`; reset=`tput sgr0`; hk="${blue})${reset}"; undl=`tput smul`; bold=`tput bold`;

# getopts
P_DEBUG=false
while getopts "q: d" o; do
    case "${o}" in
        d) P_DEBUG=true ;;
    esac
done
shift $(($OPTIND - 1))

#
#       _jq
#       Decodes and search for json key/value
#       $1 --> json
#       $2 --> key
#
function _jq() {
    echo ${1} | base64 --decode | jq -r ${2}
}

# Validate & Read JSON
jq -e type ./json.json >/dev/null 2>&1 || echo -e 'Invalid JSON!'
raw=`jq . ./json.json`

# Search for server
reached_end=false
while [[ $reached_end == false ]]; do

    # Show id & name of each group
    for row in $(jq -r '.g[] | @base64' <<< $raw); do
        echo -e "${prefix}    $(_jq $row '.id')${hk}  $(_jq $row '.name')"
    done

    # Debug
    exit 22
done

标签: bashjq

解决方案


这种方法比真正需要的要复杂得多。这是否符合您的要求?

< json.json jq --arg prefix "${prefix}" --arg hk "${hk}" -r \
  '.g[] | "\($prefix)    \(.id) \($hk)  \(.name)"'

for这完全用一个调用替换了循环jq,使用 jq 来进行字符串格式化而不是echo,消除了 base64 编码和解码,并消除了每行四个子进程调用。


推荐阅读