システムについてより早く学ぶために.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
演算子はシェルの関連文字列を参照します。与えられた例では、次のコードが実行されます。
_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'
この簡単なアプローチの1つの問題は、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
}
"