简单解决的关键是泛型函数aggregate_by:
# In this formulation, f must either always evaluate to a string or
# always to an integer, it being understood that negative integers
# might be problematic
def aggregate_by(s; f; g):
reduce s as $x (null; .[$x|f] += [$x|g]);
如果 CSV 可以通过简单地以逗号分隔来准确解析,则可以使用以下 jq 过滤器完成所需的转换:
aggregate_by(inputs | split(","); .[0]; .[1])
这假定 jq 是使用 -R(原始)和 -n 选项调用的。
输出
使用给定的 CSV 输入,输出将是:
{
"b00nw33": [
"harrypotter788.flv",
"harrypotter788.mov",
"levitation271.avi"
],
"b01spider": [
"schimbvalutar109.avi"
]
}
处理重要的 CSV
上述解决方案假定 CSV 与示例一样简单。相反,如果无法通过简单地以逗号分隔来准确解析 CSV,则需要更通用的解析器。
一种方法是在https://github.com/fadado/CSV 使用非常强大且快速的 csv2json 解析器
或者,您可以使用许多可用的“csv2tsv”解析器之一来生成 jq 可以直接处理的 TSV(通过在选项卡上拆分,即 split("\t") 而不是 split(","))。
无论如何,一旦将 CSV 转换为 JSON,就可以使用上面定义的过滤器aggregate_by。
如果您对 CSV 的 jq 解析器感兴趣,您可能需要查看 fromcsvfile (https://gist.github.com/pkoppstein/bbbbdf7489c8c515680beb1c75fa59f2);也可以看看
fromcsv 的定义在 https://github.com/stedolan/jq/issues/1650#issuecomment-448050902 提出