Ric*_*haw 50 bash json escaping
我正在使用git,然后将提交消息和其他位作为JSON有效负载发布到服务器.
目前我有:
MSG=`git log -n 1 --format=oneline | grep -o ' .\+'`
Run Code Online (Sandbox Code Playgroud)
它将MSG设置为:
Calendar can't go back past today
Run Code Online (Sandbox Code Playgroud)
然后
curl -i -X POST \
-H 'Accept: application/text' \
-H 'Content-type: application/json' \
-d "{'payload': {'message': '$MSG'}}" \
'https://example.com'
Run Code Online (Sandbox Code Playgroud)
我真正的JSON有另外两个领域.
这样可以正常工作,但是当我有一个提交消息(例如上面带有撇号的提交消息)时,JSON无效.
如何逃脱bash所需的角色?我不熟悉这种语言,所以不知道从哪里开始.更换'
有\'
会做的最小,我怀疑这份工作.
pol*_*m23 56
使用Python:
这个解决方案不是纯粹的bash,但它是非侵入性的并且处理unicode.
json_escape () {
printf '%s' "$1" | python -c 'import json,sys; print(json.dumps(sys.stdin.read()))'
}
Run Code Online (Sandbox Code Playgroud)
请注意,JSON是标准python库的一部分并且已经存在了很长时间,因此这是一个非常小的python依赖项.
或者使用PHP:
json_escape () {
printf '%s' "$1" | php -r 'echo json_encode(file_get_contents("php://stdin"));'
}
Run Code Online (Sandbox Code Playgroud)
使用如下:
$ json_escape "???"
"\u30e4\u30db\u30fc"
Run Code Online (Sandbox Code Playgroud)
che*_*ner 43
而不是担心如何正确引用数据,只需将其保存到文件并使用允许选项的@
构造.要确保正确转义输出以用作JSON值,请使用类似生成JSON 的工具,而不是手动创建它.curl
--data
git
jq
jq -n --arg msg "$(git log -n 1 --format=oneline | grep -o ' .\+')" \
'{payload: { message: $msg }}' > git-tmp.txt
curl -i -X POST \
-H 'Accept: application/text' \
-H 'Content-type: application/json' \
-d @git-tmp.txt \
'https://example.com'
Run Code Online (Sandbox Code Playgroud)
您也可以直接使用标准输入读取-d @-
; 我把它作为练习让读者构建从中读取git
并生成正确有效负载消息的管道curl
.
(提示:这是jq ... | curl ... -d@- 'https://example.com'
)
jch*_*ook 20
jq
可以做到这一点.
轻量级,免费和用C语言编写,jq
在GitHub上享有超过12.5k的明星社区支持.我个人觉得它在我的日常工作流程中非常快速有用.
jq -aRs . <<< '????'
Run Code Online (Sandbox Code Playgroud)
解释,
-a
表示"ascii输出"-R
意思是"原始输入"-s
表示"输出JSON文档的根".
将字符串传递给stdin(仅限bash?)要修复OP给出的代码示例,只需通过jq管道.
MSG=`git log -n 1 --format=oneline | grep -o ' .\+' | jq -aRs .`
Run Code Online (Sandbox Code Playgroud)
xsg*_*don 16
当我遇到这个问题时,我还试图在Bash中转义字符,以便使用JSON进行传输.我发现实际上有一个更大的字符列表必须被转义 - 特别是如果你试图处理自由格式文本.
我发现有两个有用的提示:
${string//substring/replacement}
此线程中描述的Bash 语法.我想出的最终Bash替换如下:
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//\\/\\\\} # \
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//\//\\\/} # /
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//\'/\\\'} # ' (not strictly needed ?)
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//\"/\\\"} # "
JSON_TOPIC_RAW=${JSON_TOPIC_RAW// /\\t} # \t (tab)
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//
/\\\n} # \n (newline)
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//^M/\\\r} # \r (carriage return)
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//^L/\\\f} # \f (form feed)
JSON_TOPIC_RAW=${JSON_TOPIC_RAW//^H/\\\b} # \b (backspace)
Run Code Online (Sandbox Code Playgroud)
我还没有在这个阶段找到如何正确地转义Unicode字符,这也是(显然)需要的.如果我解决这个问题,我会更新我的答案.
Ric*_*haw 11
好的,找到了该怎么做.Bash按预期原生支持,但一如既往,语法不是很容易猜到!
基本上${string//substring/replacement}
返回您的图像,以便您可以使用
MSG=${MSG//\'/\\\'}
Run Code Online (Sandbox Code Playgroud)
去做这个.下一个问题是第一个正则表达式不再起作用,但可以替换为
git log -n 1 --pretty=format:'%s'
Run Code Online (Sandbox Code Playgroud)
最后,我甚至不需要逃避它们.相反,我只是把JSON中的所有'换成了'.嗯,你每天都学到一些东西.
git log -n 1 --format=oneline | grep -o ' .\+' | jq --slurp --raw-input
Run Code Online (Sandbox Code Playgroud)
上一行对我有用。请参阅
https://github.com/stedolan/jq了解更多jq
工具