我需要使用 bash 和 jq v1.6 将一堆 csv 文件转换为 json。 (由于对允许在服务器上运行的脚本类型的限制,我不能使用其他脚本语言)。 JSON 或 jq 都不是我技能的重要组成部分。
我需要使用 csv 文件名作为 json 对象名称,读取 csv 以从 header 中获取字段名,并进行一些重新映射以将“所有者”移动到列表(数组?)名称。
所以,拿这个:
serverset1.csv
location,category,ip,owner
set1rack1,webserver,127.0.0.1,Customer1
set1rack2,appserver,127.0.0.2,Customer1
set1rack1,webserver,127.0.0.3,Customer2
set1rack2,appserver,127.0.0.4,Customer2
对此
[
{
"serverset1":[
{
"Customer1":[
{
"location":"set1rack1",
"category":"webserver",
"address":"127.0.0.1"
},
{
"location":"set1rack2",
"category":"appserver",
"address":"127.0.0.2"
}
],
"Customer2":[
{
"location":"set1rack1",
"category":"webserver",
"address":"127.0.0.3"
},
{
"location":"set1rack2",
"category":"appserver",
"address":"127.0.0.4"
}
]
}
]
}
]
我做到了这一点:
filename="serverset1.csv"; \
cat "$filename" | jq --slurp --raw-input --raw-output \
'
split("\n") | .[1:] | map(split(",")) |
map(
{
"location": .[0],
"category": .[1],
"address": .[2],
"owner": .[3]
}
)
'
产生这个:
[
{
"location": "set1rack1",
"category": "webserver",
"address": "127.0.0.1",
"owner": "Customer1"
},
{
"location": "set1rack2",
"category": "appserver",
"address": "127.0.0.2",
"owner": "Customer1"
},
{
"location": "set1rack1",
"category": "webserver",
"address": "127.0.0.3",
"owner": "Customer2"
},
{
"location": "set1rack2",
"category": "appserver",
"address": "127.0.0.4",
"owner": "Customer2"
}
]
但后来我遇到了语法墙。
感谢任何帮助。
~杰米
最佳答案
使用input_filename
获取输入文件名。要跳过第一行,请使用不带 -n 选项的 inputs
:
jq -R '
inputs
| [splits(", *")] as $row
| {(input_filename): { ($row[3]): $row[:3] }}
' serverset1.csv
这会生成一个“文件名”对象流,然后您可以通过修改脚本(而不是再次调用 jq)轻松地将其组装成一个数组。
如果输入文件没有头文件,则使用-n 命令行选项。
注意事项
jq 可以读取非常简单的 CSV 文件,但不太适合读取一般的 CSV 文件。如果 jq 无法轻松正确读取您的 CSV 文件,您可以使用众多出色的替代方法之一将 CSV 文件转换为 TSV 文件。
上述程序不会尝试将数字或 bool 字符串转换为 JSON 数字或 bool 值;然而,通过对上述程序进行适当的调整,可以使用 jq 轻松完成任何此类转换。
关于json - 使用 jq,将 csv 文件转换为 json,使用 csv 文件名作为顶级对象名称,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66130421/