나는 대해 알고있다연관 배열에서 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
가능한 해결책 중 하나는 다음과 같습니다.
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
로 전달됩니다( 사용되는 경우 항상 마지막 옵션이어야 함). 유틸리티 는 키와 값을 단일 배열로 받습니다 . 즉, 배열의 첫 번째 절반에는 키가 포함되고 배열의 두 번째 절반에는 해당 값이 포함됩니다.jq
--args
--args
jq
$ARGS.positional
표현식의 본문은 jq
출력 객체를 생성하고 reduce
0부터 시작하는 정수 범위에서 작동합니다. 여기서 는 배열의 요소 수입니다. 이 작업은 :th 매개변수를 키로 사용하고 + :th 매개변수를 해당 배열 값의 요소로 사용하여 위치 매개변수를 하나씩 추가하여 객체를 만듭니다.$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
그러면 세 개의 개체가 출력됩니다.
{"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})'