jq
내 목표는 bash의 명령 출력을 사용하여 JSON 개체를 출력하는 것입니다. find
한 줄 명령일 수도 있고 bash 스크립트일 수도 있습니다.
각 출력 줄에서 JSON 개체를 생성하는 다음 명령이 있습니다.
find ~/ -maxdepth 1 -name "D*" | \
while read line; \
do jq -n \
--arg name "$(basename "$line")" \
--arg path "$line" \
'{name: $name, path: $path}'; \
done
출력은 다음과 같습니다.
{
"name": "Desktop",
"path": "/Users/username/Desktop"
}
{
"name": "Documents",
"path": "/Users/username/Documents"
}
{
"name": "Downloads",
"path": "/Users/username/Downloads"
}
하지만 이러한 객체가 배열에 있어야 하고 해당 배열이 items
다음과 같이 상위 객체의 단일 키 값이 되도록 해야 합니다.
{"items": [
{
"name": "Desktop",
"path": "/Users/username/Desktop"
},
{
"name": "Documents",
"path": "/Users/username/Documents"
},
{
"name": "Downloads",
"path": "/Users/username/Downloads"
}
]
}
jq
각 줄의 출력 문자열에 대괄호를 추가하고( '[{name: $name, path: $path}]';
) 대괄호를 추가 했지만 배열 요소 사이에 쉼표는 추가하지 않았습니다.
가능한 해결책을 찾았습니다여기하지만 각 행을 반복하면서 사용하는 방법을 모르겠습니다.
답변1
이 jq 1.5
inputs
스트리밍 필터 트릭이 효과가 있는 것 같습니다.
... | jq -n '.items |= [inputs]'
전임자.
$ find ~/ -maxdepth 1 -name "D*" |
while read line; do
jq -n --arg name "$(basename "$line")" \
--arg path "$line" \
'{name: $name, path: $path}'
done | jq -n '.items |= [inputs]'
{
"items": [
{
"name": "Downloads",
"path": "/home/steeldriver/Downloads"
},
{
"name": "Desktop",
"path": "/home/steeldriver/Desktop"
},
{
"name": "Documents",
"path": "/home/steeldriver/Documents"
}
]
}
답변2
jq
호출에서 직접 find
결과 데이터를 사용하여 jq
셸 루프 없이 최종 출력을 빌드합니다.
find ~ -maxdepth 1 -name '[[:upper:]]*' \
-exec jq -n --arg path {} '{ name: ($path|sub(".*/"; "")), path: $path }' \; |
jq -n -s '{ items: inputs }'
발견된 각 경로 이름에 대해 JSON 개체를 생성하여 실행됩니다 jq
. -exec
값의 마지막 슬래시까지 경로 이름의 모든 내용을 제거 name
하고 경로 이름을 그대로 값으로 사용합니다 path
.
마지막으로 jq
데이터를 find
배열 로 읽은 -s
다음 items
새 JSON 개체에 배열로 삽입합니다. 최종 jq
호출은 다음과 같이 작성할 수도 있습니다 jq -n '{ items: [inputs] }
.
[[:upper:]*
결과 예( 대체 패턴을 사용하고 있음에 유의하세요 D*
):-name
find
{
"items": [
{
"name": "Documents",
"path": "/home/myself/Documents"
},
{
"name": "Mail",
"path": "/home/myself/Mail"
},
{
"name": "Work",
"path": "/home/myself/Work"
}
]
}
답변3
프로그래밍 언어를 사용하는 것이 마음에 들지 않는다면 매우 간단합니다. 다음은 PHP 예제입니다:
<?php
$m1 = [
'items' => []
];
$a1 = glob('~/D*');
foreach ($a1 as $s1) {
$m1['items'][] = [
'name' => basename($s1),
'path' => $s1
];
}
echo json_encode($m1, JSON_PRETTY_PRINT);