我正在制作一个 .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
}
"