I have one stream output stored in csv file, I need help converting csv to json:
my csv looks like:
cat output.csv
"k","a1",1,"b1","c1","d1",1
"l","a2",2,"b2","c2","d2",2
"m","a3",3,"b3","c3","d3",3
"n","a4",4,"b4","c4","d4",4
"o","a5",5,"b5","c5","d5",5
Required output:
note: I need key configuration
to be added to json.
{
"configuration": {
"k": {
"a": "a1",
"number1": "1",
"c": "b1",
"d": "c1",
"e": "d1",
"number2": "1"
},
"l": {
"a": "a2",
"number1": "2",
"c": "b2",
"d": "c2",
"e": "d2",
"number2": "2"
},
.
.
.
}
}
So far tried with jq:
my function is:
cat api.jq
[
inputs |
split(",") |
map(ltrimstr(""")) |
map(rtrimstr(""")) |
{
a: .[1],
number1: .[2],
c: .[3],
d: .[4],
e: .[5],
number2: .[6]
}
] | {configuration: .}
Output:
jq -nRf api.jq output.csv
{
"cluster_configuration": [
{
"a": "a1",
"number1": "1",
"c": "b1",
"d": "c1",
"e": "d1",
"number2": "1"
},
{
"a": "a2",
"number1": "2",
"c": "b2",
"d": "c2",
"e": "d2",
"number2": "2"
},
{
"a": "a3",
"number1": "3",
"c": "b3",
"d": "c3",
"e": "d3",
"number2": "3"
},
{
"a": "a4",
"number1": "4",
"c": "b4",
"d": "c4",
"e": "d4",
"number2": "4"
},
{
"a": "a5",
"number1": "5",
"c": "b5",
"d": "c5",
"e": "d5",
"number2": "5"
}
]
}
5
Answers
jq’s
from_entries
can be used to generate objects with chosen keys.In the below example, we first use Miller to convert CSV to JSON more robustly (in a manner that supports values with commas or quotes) before proceeding with
jq
Add a header line at the top so Miller knows what key name to associate with each value:
Convert the csv to json with miller:
transform with jq, generating lists of maps with
key
andvalue
elements and then combining them withfrom_entries
:This results in:
All together as a oneliner:
Insofar as your goal is to make
a
be a key, usingfrom_entries
is suitable for that:When run with
…the output is:
If robustness of CSV parsing is a concern, you could easily adapt
the parser at rosettacode.org. The following converts the CSV rows to JSON arrays; since the "main" program below uses
inputs
, you’d use the -R and -n command-line options.I know you raise this question as a
bash+jq
question, but, if it was abash+python
question, the solution would be trivial:Then, in bash (I’m assuming Ubuntu here), we could go:
Here’s a possible solution with Miller (available here for several OSs), an interesting tool that supports multiple input/output formats:
note: for forcing the numbers to be treated as strings you can use the
--infer-none
option.