find "$HOME" -maxdepth 1 -type d
이 명령을 사용하여 다음과 같은 결과를 얻었다 고 가정해 보겠습니다 .
/home/user/folder1
/home/user/folder2
/home/user/folder3
/home/user/folder4
jq
파이프라인에서 사용하고 다음과 같은 다양한 JSON 라인을 생성하고 싶습니다 .
{ "path": "/home/user/folder1", "type":"directory"}
{ "path": "/home/user/folder2", "type":"directory"}
{ "path": "/home/user/folder3", "type":"directory"}
{ "path": "/home/user/folder4", "type":"directory"}
jq
폴더 목록을 배열에 넣고 루프에서 하나씩 생성하는 것을 피하기 위해 이 문제를 해결하고 싶습니다 . 의사코드에서 아이디어는 다음과 같습니다.
find "$HOME" -maxdepth 1 -type d | jq '.logic-to-create-json-strings'
그것은 사용될 수 있습니까 jq
?
답변1
이 답변에서는 파일 이름(또는 JSON 인코딩하려는 텍스트)이 유효한 UTF-8이라고 가정합니다.
두 가지 옵션:
사용되지 않음 : 위치 인수로 pathname을 xargs
직접 호출합니다. jq
찾은 경로 이름을 읽고 표현식의 배열로 액세스합니다. 각 경로 이름에 대해 JSON 개체가 생성됩니다.find
-exec
--args
$ARGS.positional
jq
find "$HOME" -maxdepth 1 -type d \
-exec jq -n -c \
'$ARGS.positional[] as $path | { path: $path, type: "directory" }' \
--args {} +
사용법 xargs
: -print0
with find
및 -0
with 를 사용 하여 xargs
찾은 경로 이름을 안전하게 전달합니다 . 경로 이름이 와 사이에 전달되는 방식이 다른 점을 제외하면 표현식은 위와 동일합니다 .find
xargs
jq
find
jq
find "$HOME" -maxdepth 1 -type d -print0 |
xargs -0 jq -n -c \
'$ARGS.positional[] as $path | { path: $path, type: "directory" }' --args
위의 두 가지 방법을 모두 사용하면 jq
발견된 경로 이름이 JSON 문자열로 표시될 수 있도록 인코딩됩니다.
다른 jq
말로 표현하면 효과는 같습니다.
$ARGS.positional[] as $path | { path: $path, type: "directory" }
예
$ARGS.positional | map({ path: ., type: "directory" })[]
읽다철사표시된 개체 집합을 사용하면 jq
표준 입력 스트림에서 읽는 다음 명령을 사용할 수 있습니다.
jq -R -c '{ path: ., type: "directory" }'
답변2
JSON은 문자열(UTF-8로 인코딩된 문자의 시퀀스)에서 임의의 파일 경로(0이 아닌 바이트의 시퀀스)를 직접 나타낼 수 없습니다. 또한 참고하시기 바랍니다출력을 find
사후 처리할 수 없습니다..-print0
예를 들어, 파일 경로는 UTF-8로 인코딩 되고 ISO-8859-1로 인코딩된 $'/home/St\xc3\xa9phane\nChazelas/ISO-8859-1/R\xe9sum\xe9'
( 여기서는 바이트 값을 나타내기 위해 ksh93
-style $'...'
표기법이 사용됨) 일 수 있습니다 .é
Stéphane
Résumé
JSON은 일부 인코딩을 사용하지 않으면 이 파일 경로를 나타낼 수 없습니다. 예를 들어 URI 인코딩일 수 있습니다.
{ "path": "/home/St%C3%A9phane\nChazelas/ISO-8859-1/R%E9sum%E9" }
또 다른 접근 방식은 경로를 ISO-8859-1 인코딩(또는 모든 바이트 값이 유효한 문자를 구성할 수 있는 단일 바이트 문자 집합)으로 해석하는 것입니다.
{ "path": "/home/Stéphane\nChazelas/ISO-8859-1/Résumé" }
jq
URI 인코딩에 대한 일부 지원이 있지만 내가 아는 한 UTF-8이 아닌 입력은 제공하지 않습니다. AFAIK, 트랜스코딩도 지원하지 않습니다.
GNU 시스템에서 파일 경로가 ISO-8859-1 인코딩으로 간주되는 두 번째 방법의 경우 다음을 수행할 수 있습니다.
find ~ -type d -print0 |
iconv -f iso-8859-1 -t utf-8 |
tr '\0\n' '\n\0' |
jq -Rc '{"path":sub("\u0000";"\n"),"type":"directory"}'
위의 예에서는 다음과 같습니다.
{"path":"/home/Stéphane\nChazelas/ISO-8859-1/Résumé.pdf","type":"directory"}
¹ iso-8859-1은 코드 포인트가 유니코드의 코드 포인트와 일치하기 때문에 확실한 선택입니다. 따라서 json 문자열에 U+00E9 문자가 포함되어 있으면 해당 문자가 0xE9 바이트에 해당한다는 것을 알 수 있습니다. 대신 ASCII가 아닌 문자를 나타내는 -a
옵션을 추가할 수 있습니다 .jq
\uXXXX