如何用jq实现特定双重笛卡尔积并生成TSV输出?
问题:NDJSON转TSV时实现labeled_values与flavors的笛卡尔积展开
输入NDJSON数据集
{"id": 99, "labeled_values": [["one", "green"], ["two", "red"], ["three", "blue"]], "flavors": ["hot", "cold"]} {"id": 100, "labeled_values": [["four", "green"], ["five", "red"]], "flavors": ["hot"]}
期望TSV输出
99 one green hot 99 two red hot 99 one green cold 99 two red cold 100 four green hot 100 five red hot
现有尝试
不含flavors字段的可行命令
$ cat tmp/foo.ndjson | jq -r '[.id] + .labeled_values[] | @tsv' 99 one green 99 two red 99 three blue 100 four green 100 five red
错误的flavors拼接尝试
直接将.flavors追加到数组会把所有flavor一次性拼接,而非逐个匹配:
$ cat tmp/foo.ndjson | jq -r '[.id] + .labeled_values[] + .flavors | @tsv' 99 one green hot cold 99 two red hot cold 99 three blue hot cold 100 four green hot 100 five red hot
正确的jq实现方案
需要对每个labeled_values元素,遍历flavors数组生成笛卡尔积组合,命令如下:
cat tmp/foo.ndjson | jq -r '.id as $id | .labeled_values[] as $lv | .flavors[] as $f | [$id] + $lv + [$f] | @tsv'
逻辑说明
- 将当前对象的
id存为变量$id,避免重复读取 - 遍历每个
labeled_values元素并存储为$lv - 对每个
$lv,再遍历每个flavors元素存储为$f - 将
$id、$lv的两个值、$f组合成数组,最后用@tsv转换为制表符分隔行
内容的提问来源于stack exchange,提问作者dfrankow
相关产品推荐
相关产品推荐

