我有一个返回一些键值对的 JSON 字符串,但如果该值是数字,它不会用双引号将其括起来,因此我的 JSON 解析不适用于这些情况。
我的想法是通过搜索和替换它找到的任何出现的地方来操作字符串:
,:"
除非 : 后面跟着一个左大括号 {
我还需要在末尾关闭双引号,因此我需要找到一种方法来查找任何 0-9 后跟逗号,并将该逗号替换为",
我想我需要 SED 来搜索/替换,但我对 SED 和 RegEx 很陌生,所以不知道如何开始,特别是省略它找到的地方"{
并使用 RegEx 来查找[0-9],
示例 JSON 字符串如下所示:
{"data":{"project":{"issue":{"session":{"id":"625fdv6b95e232f08d6cy2686624f315","createdAt":1539849060000,"buildVersionId":"75492373","sdk":{"display":"1.11.1"},"os":{"platform":"unknown","modified":false},"memory":{"free":853000192,"used":1896611840},"storage":{"free":241791528960,"used":14197940224},"device":{"architecture":"arm64","manufacturer":"Samsung"}}}}}}
更改后所需的完成 JSON 如下所示:
{"data":{"project":{"issue":{"session":{"id":"625fdv6b95e232f08d6cy2686624f315","createdAt":"1539849060000","buildVersionId":"75492373","sdk":{"display":"1.11.1"},"os":{"platform":"unknown","modified":false},"memory":{"free":"853000192","used":"1896611840"},"storage":{"free":"241791528960","used":"14197940224"},"device":{"architecture":"arm64","manufacturer":"Samsung"}}}}}}
几乎相同的事情,但现在每个数字都有双引号。
答案1
怎么样
sed 's/:\([0-9]*\)\([,}]\)/:"\1"\2/g' inp >out
s/:\([0-9]*\)\([,}]\)
- 搜索:
后跟数字,后跟,
或}
。将数字放入 capture \1,将,
or}
放入 \2。/:"\1"\2/g
- 替换为 ,:"
然后捕获 \1 (数字),然后是"
,然后捕获 \2 (原始后缀字符)
例子
$ cat inp
{"data":{"project":{"issue":{"session":{"id":"625fdv6b95e232f08d6cy2686624f315","createdAt":1539849060000,"buildVersionId":"75492373","sdk":{"display":"1.11.1"},"os":{"platform":"unknown","modified":false},"memory":{"free":853000192,"used":1896611840},"storage":{"free":241791528960,"used":14197940224},"device":{"architecture":"arm64","manufacturer":"Samsung"}}}}}}
$ sed 's/:\([0-9]*\)\([,}]\)/:"\1"\2/g' inp >out
$ cat desired
{"data":{"project":{"issue":{"session":{"id":"625fdv6b95e232f08d6cy2686624f315","createdAt":"1539849060000","buildVersionId":"75492373","sdk":{"display":"1.11.1"},"os":{"platform":"unknown","modified":false},"memory":{"free":"853000192","used":"1896611840"},"storage":{"free":"241791528960","used":"14197940224"},"device":{"architecture":"arm64","manufacturer":"Samsung"}}}}}}
$ diff out desired
$
答案2
我采用了不同的方法,没有修改 JSON 数据,而是修改了对数值的 grep 操作,而不是查找双引号,如下所示:
buildVersionId=`echo $jsonData | grep -m1 -oP '"buildVersionId"\s*:\s*\K[^"]+"'`
,"
然后我删除末尾的最后 2 个字符( )以仅获取实际数字:
buildVersionId=${buildVersionId::${#buildVersionId}-2}
答案3
jq -c '(.. | select(numbers)) |= tostring' file >newfile
此jq
命令会将 JSON 文档中的所有数字转换为字符串,无论这些数字在文档中的哪个位置找到。
输出以“紧凑”形式写入文件newfile
。
如果您出于某种原因最终将 JSON 文档放在 shell 变量中,data
则可以使用
jq -c -n --argjson d "$data" '$d | (.. | select(numbers)) |= tostring' >newfile