Bashrc 函数 case 语句从 JSON 导入案例

Bashrc 函数 case 语句从 JSON 导入案例

我正在制作一个 .bashrc 函数来让我更快地了解系统。我用案例陈述来说明我想去的地方。

function da() {
case "$1" in 
    home)   cd ~
            ;;
    eolas) cd /home/eolas/
           ;;
esac
}

我想从 JSON 文件导入案例,例如:

{
  "cases": {
    "home": "~",
    "eolas": "/home/eolas/",
    "jdan": "/home/jdan/",
    "kl": "/.kl/"
  }
}

我已经在寻找一种方法来做到这一点,但到目前为止还没有找到,这在 bash 中可能吗?如果是这样怎么办?

答案1

如果你有一个 JSON 文件,你应该自动考虑使用来解析它。

您需要将该文件读入关联数组:

declare -A __dirmap
while IFS=$'\t' read -r name dir; do
    [[ $dir == "~" ]] && __dirmap[$name]=$HOME || __dirmap[$name]=$dir
done < <(
    jq -r '.cases | to_entries[] | [.key, .value] | @tsv' file.json
)

那么函数可以是

function da() {
    if [[ -v __dirmap[$1] ]]; then
        cd "${__dirmap[$1]}"
    else
        echo "No mapping for $1" >&2
    fi
}

答案2

我将使用您的 JSON 构建案例标签及其相应目录的关联数组。这可以在您的文件中完成一次~/.bashrc

unset _da_map
declare -A _da_map

if [ -f da_map.json ]; then
    eval "$(
            jq -r '.cases | to_entries[] |
                   @sh "_da_map[\(.key)]=\(.value)"' da_map.json
    )"
fi

(或者将其放在一个单独的da_init函数中,以便您可以在更改文件时调用它da_map.json。)

jq语句构建了许多要eval评估的变量赋值。该@sh运算符引用 shell 的相关字符串。对于给定的示例,这将导致运行以下代码:

_da_map['home']='~'
_da_map['eolas']='/home/eolas/'
_da_map['jdan']='/home/jdan/'
_da_map['kl']='/.kl/'

da函数可以写成

da () {
        command cd -- "${_da_map["$1"]?No mapping for label "'$1'"}"
}

这使用先前创建到cd与给定参数关联的目录的关联数组。如果没有找到给定参数的映射,则扩展会生成错误:

$ da "hello world"
bash: _da_map["$1"]: No mapping for label 'hello world'

这种简单方法的一个问题是,它不允许在 JSON 文件中的目录值中进行波形符扩展(或与此相关的变量扩展)。因此,您应该在不使用~变量和不使用变量的情况下编写路径。

答案3

不完全优雅,但似乎有效:

in='
{
  "cases": {
    "home": "~",
    "eolas": "/home/eolas/",
    "jdan": "/home/jdan/",
    "kl": "/.kl/"
  }
}
'

case="$(echo "$in" |
          perl -pe 's/"cases". \{/case "\$1" in/;
                    s/: /) eval cd /;
                    s/,/;;/;
                    s/[{}]//g')"

eval "
  function da() {
      $case
    esac
  }
"

相关内容