从JSON文件中删除转义序列字符,如换行符、制表符和回车符。

16

我有一个包含80多个字段的JSON。在使用jq提取下面提到的JSON文件中的消息字段时,我得到了换行符和制表符。我想要删除转义序列字符,并尝试使用sed进行操作,但没有成功。

示例JSON文件:

{
"HOSTNAME":"server1.example",
"level":"WARN",
"level_value":30000,
"logger_name":"server1.example.adapter",
"content":{"message":"ERROR LALALLA\nERROR INFO NANANAN\tSOME MORE ERROR INFO\nBABABABABABBA\n BABABABA\t ABABBABAA\n\n BABABABAB\n\n"}
}

有人能帮我解决这个问题吗?


所以你从未想过在那个文件中加入换行符或制表符?还是一个文件中有多个条目?(请更新您的问题,我会删除此评论)。祝好运。 - shellter
1
如果您使用 -r 选项,jq 将把转义序列转换为实际的换行符、制表符等。这是您想要的吗?jq -r .content.message file.json - hek2mgl
1
不,我想要去除换行和制表符空格。 - user3792699
2
为了清晰起见,请将期望的输出与示例输入匹配添加到您的问题中(仍有一个歧义,即您是否也想去掉封闭的双引号)。 - mklement0
3个回答

28

一种jq解决方案:

$ jq -r '.content.message | gsub("[\\n\\t]"; "")' file.json
ERROR LALALLAERROR INFO NANANANSOME MORE ERROR INFOBABABABABABBA BABABABA ABABBABAA BABABABAB

如果你想保留引号",则省略-r
注意:peak的有用答案包含一个通用正则表达式,通过Unicode类别指定符\p{Cc}匹配ASCII和Latin-1 Unicode范围内的所有控制字符。 jq使用Oniguruma正则表达式引擎。
其他解决方案,使用额外的实用程序,例如sedtr
使用sed无条件删除转义序列\nt
$ jq '.content.message' file.json | sed 's/\\[tn]//g'
"ERROR LALALLAERROR INFO NANANANSOME MORE ERROR INFOBABABABABABBA BABABABA ABABBABAA BABABABAB"

请注意,尽管如此,包含在 " 中的引号仍然存在。 要删除它们,请向 sed 命令添加另一个替换:
$ jq '.content.message' file.json | sed 's/\\[tn]//g; s/"\(.*\)"/\1/'
ERROR LALALLAERROR INFO NANANANSOME MORE ERROR INFOBABABABABABBA BABABABA ABABBABAA BABABABAB

另一个更简单的选项是同时删除包含的"(注意:输出没有尾随的\n):

$ jq -r '.content.message' file.json | tr -d '\n\t'
ERROR LALALLAERROR INFO NANANANSOME MORE ERROR INFOBABABABABABBA BABABABA ABABBABAA BABABABAB

请注意,-r 用于使 jq 对字符串进行内插(扩展 \n 和 \t 序列),然后这些序列被识别为字面量并由 tr 移除。

8

通过您的输入,以下咒语会被施展:

$ jq 'walk(if type == "string" then gsub("\\p{Cc}"; "<>") else . end)' 

生成:

{
  "HOSTNAME": "server1.example",
  "content": {
    "message": "ERROR LALALLA<>ERROR INFO NANANAN<>SOME MORE ERROR INFO<>BABABABABABBA<> BABABABA<> ABABBABAA<><> BABABABAB<><>"
  },
  "level": "WARN",
  "level_value": 30000,
  "logger_name": "server1.example.adapter"
}

当然,上述调用只是举例说明:
- 你可能根本不需要使用walk/1。(walk/1遍历输入的JSON。) - 你可能想使用不同的字符类,或指定一系列gsub/2的调用。 - 如果你只想删除控制字符,请将第二个参数指定为"",并不使用gsub/2
如果你确实想要使用walk/1,但你的jq命令没有它,那么只需在调用之前添加它的定义(可以轻松地在网络上找到,如这里)。

++ 对于一些高级技术来说确实很有用,但是说实话,从你的回答中可以得出一个简单的 jq -r '.content.message | gsub("[\\n\\t]"; "")' file.json 解决方案,但这个解决方案被偶然的/概括性信息所掩盖。 - mklement0
@mklement0 - (1)问题中包含“来自JSON文件”的短语,并提到了大量字段。由于不清楚实际需要什么,我认为一般有用的答案会更加普遍有用:-))(2)问题通常提到“转义序列字符”,特别是TAB,NL和CR,而您在这些评论中提到的解决方案并未涵盖所有三个。 - peak
公正的观点 - 描述本身常常存在歧义,而且描述和示例数据之间存在不一致(“换行符和制表符[sic]”与“转义序列”并列提到)。我个人认为你的回答非常有用,也从中学到了东西,但我的观点是,更多上下文的“温和”框架可能会更有帮助。 - mklement0

2

使用 jq v1.6 可以实现以下功能

jq -rc ".content.message" file.json

由于只提取了一个字符串值,-c (--compact-output) 在这里没有任何效果,并且您的解决方案并不符合问题的要求(删除换行符和制表符)。 - mklement0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接