为什么 jq --raw-output 参数无法从 @csv 输出中删除引号?
Why does the jq --raw-output argument fail to remove quotes from @csv output?
我正在尝试使用 jq
将 ffprobe
生成的 JSON 输出的某些元素重新格式化为 csv
。我很接近(在我看来),但在细节上苦苦挣扎:
我的ffprobe
output is shown in the jq 1.6 playground
我是 运行 最近 d/l jq (jq --version
=> jq-1.6
) 在 MacOS Mojave ( 10.14.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
输出(如上所示)不是我需要的...我需要没有 周围引号 ""
的值 。根据 the documentation 对于 --raw-output / -r
:
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. This can be useful for making jq filters talk to non-JSON-based systems.
此外,使用 @tsv
而不是 @csv
“ 做正确的事 ” 似乎很奇怪,因为引号将被删除。我想可以做一些额外的工作来用 ,
替换 tab
个字符,但我想知道在回到那种方法之前我是否遗漏了什么。
@csv
过滤器通常根据流行标准生成 CSV,该标准要求在某些情况下对字符串进行引号(例如,如果它们包含逗号),并且允许对字段进行引号。
jq 的 -r 选项被很多人误解了。它只影响 "top-level" JSON 字符串输出。它应该与 @csv
选项一起使用以生成 CSV 输出,但它不会从字符串值字段中去除引号。
如果您想对引号出现的位置进行细粒度控制,您有多种选择(最简单的选择之一是 @tsv | gsub("\t";",")
),但是 运行 产生无效的风险CSV.
--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
将 ffprobe
生成的 JSON 输出的某些元素重新格式化为 csv
。我很接近(在我看来),但在细节上苦苦挣扎:
我的ffprobe
output is shown in the jq 1.6 playground
我是 运行 最近 d/l jq (jq --version
=> jq-1.6
) 在 MacOS Mojave ( 10.14.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
输出(如上所示)不是我需要的...我需要没有 周围引号 ""
的值 。根据 the documentation 对于 --raw-output / -r
:
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. This can be useful for making jq filters talk to non-JSON-based systems.
此外,使用 @tsv
而不是 @csv
“ 做正确的事 ” 似乎很奇怪,因为引号将被删除。我想可以做一些额外的工作来用 ,
替换 tab
个字符,但我想知道在回到那种方法之前我是否遗漏了什么。
@csv
过滤器通常根据流行标准生成 CSV,该标准要求在某些情况下对字符串进行引号(例如,如果它们包含逗号),并且允许对字段进行引号。
jq 的 -r 选项被很多人误解了。它只影响 "top-level" JSON 字符串输出。它应该与 @csv
选项一起使用以生成 CSV 输出,但它不会从字符串值字段中去除引号。
如果您想对引号出现的位置进行细粒度控制,您有多种选择(最简单的选择之一是 @tsv | gsub("\t";",")
),但是 运行 产生无效的风险CSV.
--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
,但是当某些字符串本身包含逗号时,它不会很好地工作。