为什么使用jq --raw-output参数无法从@csv输出中删除引号?

7
我正在尝试使用jq来重新格式化ffprobe生成的JSON输出中的一些元素为csv。我已经接近成功,但在一个细节上遇到了困难:
我的jq 1.6 playground中显示了ffprobe的输出 我在MacOS Mojave(10.14.6)上运行最近下载的jq二进制文件(jq --version => jq-1.6
从我的Mac终端上,我的结果是:
$ fn_ffprobeall | jq -r '[.format.filename,.format.format_name,.format.tags.album_artist] | @csv'
"01 Jubilee.flac","flac","Bill Charlap Trio"

# where fn_ffprobeall is a function defined as: 
fn_ffprobeall () { ffprobe -i "01 Jubilee.flac" -hide_banner -v quiet -print_format json -show_format -show_streams; }

但是这个(jq)输出(如上所示)不是我需要的... 我需要没有周围带有引号("")的值。根据--raw-output / -r文档

使用此选项时,如果过滤器的结果是字符串,则该字符串将直接写入标准输出,而不是格式化为带引号的JSON字符串。这对于使jq过滤器与非基于JSON的系统通信非常有用。

此外,似乎使用 @tsv 而不是 @csv 会执行正确操作,因为引号将被剥离。我认为可以做一些额外的工作,以将 tab 字符替换为 ,,但我想知道是否遗漏了某些内容,在回退到该方法之前。
2个回答

9
--raw-output选项不对传递给@csv函数的字符串产生影响,因为在这个阶段它们还不是筛选结果的最终值。由于@csv加上引号,所以它们被引用了。 jq@csv函数的结果视为单个字符串输出值。--raw-output选项像文档中所说的那样工作,它不会将字符串结果编码为JSON。
如果你不使用该选项,你将看到输出为"\"01 Jubilee.flac\",\"flac\",\"Bill Charlap Trio\"",这是一个正确编码的JSON字符串。它有引号,并且已经转义了一些特殊字符。 你可以通过简单地勾选和取消勾选https://jqplay.org/s/OerK1MlARS页面上的Raw Output选项来查看这种差异。
如果你想要CSV中没有引号的字符串,你可以用join(",")代替@csv,但当某个字符串本身包含逗号时,它将无法很好地工作。

我理解你的解释 - 很有道理。但愿 jq 的文档也能这么清晰 :) 另外,我试图使用 Excel 将字符串作为现有 CSV 文件中的一行添加。 - user5395338

3
@csv 过滤器生成符合普遍标准的 CSV,这些标准要求在特定情况下(例如包含逗号的字符串)对字符串进行引号处理,并允许对字段进行引号处理。
jq 的选项 -r 经常被误解。它仅影响“顶级” JSON 字符串输出。 它应该与 @csv 选项一起使用以生成 CSV 输出,但它不会从字符串值字段中删除引号。
如果您想对引号出现的位置进行细粒度控制,您有多种选项可供选择,其中最简单的之一是 @tsv | gsub("\\t";","),但这样做可能会产生无效的 CSV。

好的,"标准"有点模糊也是可以理解的。在阅读了您的回答后,我发现了RFC 4180,其中提供了一些见解。您的回答中说:"jq-r选项被误解了很多。它应该是..." 我可能不理解您想表达什么... 我确实使用了@csv选项,并且文档清楚地说明(就我所读到的)引号将被剥离。您能澄清一下被误解的是什么吗? - user5395338
你如何将此与文档相符?:“使用此选项,如果过滤器的结果是字符串,则直接写入标准输出,而不是格式化为带引号的 JSON 字符串。” - user5395338
也许这就是我们共同的问题:心理障碍? - user5395338

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