
私は知っています連想配列からJSONを生成する方法しかし、それは私の問題ではありません。
次の連想配列があります。
declare -A aliases
aliases[Index]=components/Index/Exports
aliases[Shared]=components/Shared/Exports
aliases[Icons]=components/Icons/Exports
この連想配列を次のJSONに変換する必要があります。
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"Index": ["components/Index/Exports"],
"Shared": ["components/Shared/Exports"],
"Icons": ["components/Icons/Exports"],
}
}
}
jo
とを使用したいjq
。しかし、ネストがわかりません。
私はこのコードを試しました:
jo -p compilerOptions[baseUrl]=. compilerOptions[paths]="$(jo -p a ${Aliases[@]})"
しかし、実行すらされません。
答え1
考えられる解決策の1つは次のとおりです。
declare -A aliases
aliases[Index]=components/Index/Exports
aliases[Shared]=components/Shared/Exports
aliases[Icons]=components/Icons/Exports
jq -n --argjson n "${#aliases[@]}" '
{ compileroption: {
baseurl: ".",
paths:
(
reduce range($n) as $i ({};
.[$ARGS.positional[$i]] = [$ARGS.positional[$i+$n]]
)
)
} }' --args "${!aliases[@]}" "${aliases[@]}"
jo
連想配列を使用する代わりに、キーと値はコマンドの最後に位置引数aliases
として渡されます(使用される場合は常に最後のオプションでなければなりません)。ユーティリティはキーと値を単一の配列として受け取ります。つまり、配列の最初の半分にキーが含まれ、配列の2番目の半分に対応する値が含まれます。jq
--args
--args
jq
$ARGS.positional
式の本文は、jq
出力オブジェクトを生成し、reduce
ゼロから始まる整数範囲で機能します。ここでは、配列の要素数です。この操作では、 :th パラメーターをキーとして使用し、 + :th パラメーターをその配列値の要素として使用して、位置パラメーターを 1 つずつ追加してオブジェクトを作成します。$n
$n
aliases
reduce
paths
$i
$i
$n
jo
連想配列の各キーと値のペアに対してリーフオブジェクトを作成する方法は少し異なります。
declare -A aliases
aliases[Index]=components/Index/Exports
aliases[Shared]=components/Shared/Exports
aliases[Icons]=components/Icons/Exports
for key in "${!aliases[@]}"; do
jo "$key[]=${aliases[$key]}"
done
これにより、3つのオブジェクトが出力されます。
{"Icons":["components/Icons/Exports"]}
{"Index":["components/Index/Exports"]}
{"Shared":["components/Shared/Exports"]}
私たちはこれをこのように使用しているので、jo
配列のキーにいくつかの明白な制限を適用します(=
などを含めない場合があります[]
)。
私たちはこれを次jq
のように使用できますjo
:
for key in "${!aliases[@]}"; do
jq -n --arg key "$key" --arg value "${aliases[$key]}" '.[$key] = [$value]'
done
その後、それを読み取り、作成中のオブジェクトの正しい場所に追加できますjq
。
declare -A aliases
aliases[Index]=components/Index/Exports
aliases[Shared]=components/Shared/Exports
aliases[Icons]=components/Icons/Exports
for key in "${!aliases[@]}"; do
jo "$key[]=${aliases[$key]}"
done |
jq -n '{ compileroptions: {
baseURL: ".",
paths: (reduce inputs as $item ({}; . += $item)) } }'
ここでの主な違いは、jq
コンテンツをコマンドラインオプションとして渡すのではなく、JSONオブジェクトストリームに渡すことです。
答え2
perl
個人的には、私はシェル(特にbash!)の代わりに他の適切なプログラミング言語を使います。または、少なくともzsh
より良い連想配列のサポートに切り替えて、perl
JSONy操作を実行するために使用してください。
#! /usr/bin/perl
use JSON;
%my_aliases = (qw(
Index components/Index/Exports
Shared components/Shared/Exports
Icons components/Icons/Exports
));
$j->{compilerOptions}->{baseUrl} = "";
$j->{compilerOptions}->{paths}->{$_} = [$my_aliases{$_}] for keys%my_aliases;
print to_json($j, {"pretty" => 1});
または:
#! /bin/zsh -
typeset -A my_aliases=(
Index components/Index/Exports
Shared components/Shared/Exports
Icons components/Icons/Exports
)
print -rNC1 -- "${(kv@)my_aliases}" |
perl -MJSON -0e '
chomp (@records = <>);
%my_aliases = @records;
$j->{compilerOptions}->{baseUrl} = "";
$j->{compilerOptions}->{paths}->{$_} = [$my_aliases{$_}] for keys%my_aliases;
print to_json($j, {"pretty" => 1})'