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

Posted

技术标签:

【中文标题】为啥 jq --raw-output 参数无法从 @csv 输出中删除引号?【英文标题】:Why does the jq --raw-output argument fail to remove quotes from @csv output?为什么 jq --raw-output 参数无法从 @csv 输出中删除引号? 【发布时间】:2020-06-06 13:43:34 【问题描述】:

我正在尝试使用jqffprobe 生成的JSON 输出的一些元素重新格式化为csv。我很接近(在我看来),但在细节上苦苦挣扎:

我的ffprobe output is shown in the jq 1.6 playground

我最近在 MacOS Mojave (10.14.6) 上运行 jq (jq --version => jq-1.6) 的 d/l 二进制文件

在我的 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 输出(如上所示)不是我需要的...我需要值没有 周围的引号""。根据the documentation为--raw-output / -r

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

此外,使用 @tsv 而不是 @csv "does the right thing" 似乎很奇怪,因为引号将被删除。我想可以做一些额外的工作来用, 替换tab 字符,但我想知道在回到这种方法之前我是否遗漏了一些东西。

【问题讨论】:

【参考方案1】:

--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 文件中。【参考方案2】:

@csv 过滤器通常根据流行标准生成 CSV,这些标准要求在某些情况下(例如,如果它们包含逗号)引用字符串,并且允许引用字段。

jq 的 -r 选项被误解了很多。它只影响“***” JSON 字符串输出。它应该与@csv 选项一起使用以生成 CSV 输出,但它不会从字符串值字段中去除引号。

如果您想对引号的出现位置进行细粒度控制,您有很多选择(最简单的一种是@tsv | gsub("\\t";",")),但您会冒产生无效 CSV 的风险。

【讨论】:

好吧,公平地说,“标准”有点糊涂。阅读您的答案后,我发现RFC 4180 增加了一些见解。你的回答是“jq's -r option is much misunderstood. It should be...”我可能不明白你想说什么......我确实将它与@csv选项一起使用,并且文档确实清楚地说明(当我阅读它们时)引号将被删除。你能澄清一下是什么被误解了吗? 您如何将其与文档相匹配?:With this option, if the filter’s result is a string then it will be written directly to standard output rather than being formatted as a JSON string with quotes. 也许这就是我们的共同点:心理障碍?

以上是关于为啥 jq --raw-output 参数无法从 @csv 输出中删除引号?的主要内容,如果未能解决你的问题,请参考以下文章

无法将参数 5 从 'SIZE_T *' 转换为 'size_t *' -- 为啥?

为啥 C# 无法从非泛型静态方法的签名推断泛型类型参数类型?

为啥“(SystemJS)无法解析所有参数”发生在Angular2中

尝试将 JSON 文件展平为 CSV 时出现错误消息

python 使用JQ从docker容器解析环境变量,然后将它们转换为参数以传递到docker run命令

为啥我的 jq / read / echo 管道会删除反斜杠?