Estou tentando criar uma ferramenta para enviar dados para um github gist por meio da API. O problema é que a API do github leva a essência content
como uma única linha com todas as sequências de escape escritas literalmente, assim:
{
"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"
}
}
Esse conteúdo é exibido da seguinte forma:
#!/bin/sh
# comment
func () {
for ((i=1;i<10;i++)); do
:
done
}
printf '%s\n' Foo bar baz
Que precisa ser convertido em:
#!/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
Existem ferramentas que fazem isso em uma ação? Se não, alguém sabe como isso poderia ser feito sed
ou com qualquer uma das ferramentas unix padrão?
Nota: Quaisquer sequências de escape literais no texto original precisarão ser escapadas para evitar que o github as interprete (no entanto, isso seria um problema secundário que não precisa necessariamente ser resolvido nesta questão, mas seria bom ter) :
ou seja:
printf '%s\n' Foo bar baz
torna-se:
printf '%s\\n' Foo bar baz
Isso lê tudo
datafile
como uma string e, em seguida, o jq apenas imprime como uma string JSON. Ele fornecerá uma string entre aspas adequada para substituir esse modelo diretamente pelo conteúdodatafile
dele. Os dados serão corretamente citados em JSON com apenas os escapes RFC 7159 usados e estarão em uma linha grande porque o JSON não permite que literais de string abranjam várias linhas.Você também pode montar todo o documento em jq com um arquivo JSON de modelo e
Versões muito recentes
jq
têm uma--rawfile f datafile
opção que você pode usar para carregar um arquivo em uma string ao invés da substituição do comando; você também pode trocar as coisas com-R --slurp --slurpfile t template.json datafile
et["test.txt"].content = .
.Eu tive que escapar de algum JSON para inclusão em outro JSON, e há uma solução muito simples:
Se você tiver um documento JSON existente
file.json
e quiser apenas inserir o conteúdo no local correto, usandojq
,Se o conteúdo deve ser codificado em base64:
Construindo o JSON do zero, usando
jo
(aproximando os metadados da saída destat
efile
):Ajuste os utilitários
stat
efile
de acordo com o seu Unix (o acima usa as opções do Linux).Resultado:
Use
%"$filename"
no lugar de@"$filename"
para obter um valor codificado em base64 para acontent
chave: