如何在bash中解析json文件时用jq删除输出中的双引号?

655
我正在使用 jq 解析 JSON 文件,如此展示 这里。 然而,字符串值的结果包含预期的 "双引号",如下所示:
$ cat json.txt | jq '.name'
"Google"

我该如何将此内容管道传输到另一个命令中以删除“”?这样我就可以得到

$ cat json.txt | jq '.name' | some_other_command
Google

我能用什么其他命令


11
请注意,“cat foo | bar”比“bar <foo”或其等价形式“<foo bar”效率要低得多,尤其是当“bar”是像“sort”这样的程序时,它可以在给定可寻址文件描述符而不是FIFO(只能从前往后读取)时并行化其操作。它意味着更多的启动开销(调用“/bin/cat”),以及用户空间和内核之间更多的上下文切换(每个内容在“cat”中进行一个“read()”,然后在“cat”中写入一个FIFO,最后再在目标程序中进行一个“read()”,而不是直接跳到最后一步)。 - Charles Duffy
4
一个差异非常大的案例是 cat foo | wc -cwc -c <foo -- 在后一种情况下,它只需执行两个系统调用,seek()tell(),即可获取文件的确切大小,无论它有多长;而在前者中,即使内容有几十GB,它也需要读取至文件末尾,因为只有 cat 直接访问原始文件,而 wc 没有请求元数据的方式。 - Charles Duffy
这是一些非常有用的信息。我在哪里可以阅读更多相关内容? - ruevaughn
2个回答

1190

使用-r(或--raw-output)选项将原始字符串作为输出发出:

jq -r '.name' <json.txt

6
如果你想去掉引号,只需将此命令的输出导入到tr -d '"'中。 - hd1
11
只有当没有直接引用时,@hd1所说才是正确的。如果某人的名字是"Mack "The Knife" Smith",你希望它变成Mack "The Knife" Smith,而不是Mack The Knife Smith。 - Charles Duffy
第一条评论说他们“只想去掉引号”,我已经做到了。像你这样的边角情况不在讨论范围内。 - hd1
22
作为一条规则,是否可以安全地忽略某个特定的边角情况需要进行显式、逐个案例的设计考虑。否则你就会陷入我们现在所处的世界,软件中充斥着各种错误,因为设计没有考虑可能输入的全部范围。也就是说——除非有人明确规定 " 绝不能作为字面数据而不是语法的情况下,假设这样的情况存在是不负责任的。(作为一个从事安全工作的人,我看到很多问题被错误地归类为“输入验证”失败,而实际上是没有针对完整输入域进行设计造成的) - Charles Duffy
3
jq需要一个文件名,因此无需使用管道或重定向文件内容。jq -r '.name' json.txt运行正常。 - grim_i_am
显示剩余4条评论

48

所以,如果一个文件只包含{"name": "Google"},那么是的。

sample='{"name":"Google"}'
echo $sample| jq '.name'

"Google"

使用--raw-output可以帮助

echo $sample| jq --raw-output '.name'

Google

但我遇到了这个问题,因为我正在使用--raw-output处理像这样的JSON数组

sample='[{"name":"Yahoo"},{"name":"Google"}]'
echo $sample | jq --raw-output 'map(.name)'

[
  "Yahoo",
  "Google"
]

我之前不明白为什么引号还在,后来看到了this post,现在我知道加上| .[]就可以解决问题了!

echo $sample | jq --raw-output 'map(.name)| .[]'

Yahoo
Google

请注意,echo $sample 本身就有缺陷。请参见 我刚刚赋值给一个变量,但是 echo $variable 显示的是其他东西! -- 总是使用带引号的 echo "$sample";或者更好的方法是 printf '%s\n' "$sample" - Charles Duffy

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