API를 통해 github gist로 데이터를 보내는 도구를 개발하려고 합니다. 문제는 github api가 요점을 content
한 줄로 취급하고 모든 이스케이프 시퀀스가 다음과 같이 문자 그대로 작성된다는 것입니다.
{
"test.txt": {
"filename": "test.txt",
"type": "text/plain",
"language": "Shell",
"raw_url": "https://gist.githubusercontent.com/jessebutryn/5c8b2a95b4b016e2fa33edee294c732b/raw/474f72ad32c843c18e9a61a228a31df6b85a8da1/test.txt",
"size": 96,
"truncated": false,
"content": "#!/bin/sh\n\n# comment\nfunc () {\n\tfor ((i=1;i<10;i++)); do\n\t\t:\n\tdone\n}\n\nprintf '%s\\n' Foo bar baz\n"
}
}
내용은 다음과 같이 나타납니다.
#!/bin/sh
# comment
func () {
for ((i=1;i<10;i++)); do
:
done
}
printf '%s\n' Foo bar baz
이는 다음으로 변환되어야 합니다.
#!/bin/sh\n\n# comment\nfunc () {\n\tfor ((i=1;i<10;i++)); do\n\t\t:\n\tdone\n}\n\nprintf '%s\\n' Foo bar baz\n
이 작업을 한 번에 수행할 수 있는 도구가 있나요? 그렇지 않다면 sed
표준 UNIX 도구를 사용하여 이를 수행하는 방법을 아는 사람이 있습니까 ?
참고: 원본 텍스트의 리터럴 이스케이프 시퀀스는 github이 해석하지 못하도록 이스케이프해야 합니다(그러나 이는 이 질문에서 반드시 해결할 필요는 없는 사소한 문제이지만 다음과 같은 경우에는 좋을 것입니다).
즉:
printf '%s\n' Foo bar baz
이 되다:
printf '%s\\n' Foo bar baz
답변1
jq -R -s '.' < datafile
datafile
그러면 모든 내용을 문자열로 읽은 다음 jq가 이를 JSON 문자열로 인쇄하게 됩니다. 내용을 템플릿으로 직접 바꾸는 데 적합한 인용 문자열을 제공합니다 datafile
. 데이터는 다음을 포함하는 올바른 JSON에 의해 참조됩니다.RFC 7159 이스케이프JSON은 문자열 리터럴이 여러 줄에 걸쳐 있는 것을 허용하지 않기 때문에 , 및 를 하나의 큰 줄에 사용합니다.
템플릿 JSON 파일을 사용하여 jq에서 전체 문서를 조합할 수도 있습니다.
jq --arg f "$(cat datafile)" '.["test.txt"].content = $f' < template.json
최신 버전에는 명령 대체를 사용하는 대신 파일을 문자열로 로드할 수 있는 옵션이 jq
있습니다 . 또한 및 를 사용하여 내용을 바꿀 수도 있습니다 .--rawfile f datafile
-R --slurp --slurpfile t template.json datafile
t["test.txt"].content = .
답변2
다른 JSON에 포함하기 위해 일부 JSON을 이스케이프해야 하며 매우 간단한 해결책이 있습니다.
$ jq @json <<< '{"Hello": "World"}'
"{\"Hello\":\"World\"}"
답변3
기존 JSON 문서가 있고 file.json
콘텐츠를 올바른 위치에 삽입하려는 경우 jq
,
jq --rawfile content test.txt '."test.txt".content |= $content' file.json
콘텐츠를 base64로 인코딩해야 하는 경우:
base64 test.txt | jq --rawfile content /dev/stdin '."test.txt".content |= $content' file.json
( jo
대략적인 합계 출력의 메타데이터)를 사용하여 처음부터 JSON을 빌드합니다.stat
file
#!/bin/sh
gist_url='some url'
filename=test.txt
jo -p "$filename"="$( jo \
filename="$filename" \
type="$( file -b --mime-type "$filename" )" \
language="$( file -b "$filename" )" \
raw_url="$gist_url" \
size="$( stat -c %s "$filename" )" \
truncated=false \
content=@"$filename" )"
Unix를 기반으로 한 조정 stat
및 유틸리티 (위의 Linux 옵션 사용)file
산출:
{
"test.txt": {
"filename": "test.txt",
"type": "text/x-shellscript",
"language": "POSIX shell script, ASCII text executable",
"raw_url": "some url",
"size": 108,
"truncated": false,
"content": "#!/bin/sh\n\n# comment\nfunc () {\n for ((i=1;i<10;i++)); do\n :\n done\n}\n\nprintf '%s\\n' Foo bar baz"
}
}
%"$filename"
대신에 @"$filename"
키의 base64 인코딩 값을 가져오려면 다음을 사용하세요 content
.
{
"test.txt": {
"filename": "test.txt",
"type": "text/x-shellscript",
"language": "POSIX shell script, ASCII text executable",
"raw_url": "some url",
"size": 108,
"truncated": false,
"content": "IyEvYmluL3NoCgojIGNvbW1lbnQKZnVuYyAoKSB7CiAgICBmb3IgKChpPTE7aTwxMDtpKyspKTsgZG8KICAgICAgICA6CiAgICBkb25lCn0KCnByaW50ZiAnJXNcbicgRm9vIGJhciBiYXoK"
}
}