1

I've data in text file in format:

alex street1 253465873 alex123@google.com
john street2 442893646 3jj33@google.com
kevin street3 125234763 ke1vn@yahoo.com

I need to convert this data to json format with headers: "name" "street" "phone" "e-mail"

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255

4 Answers4

4

You can read raw input and split it into space-delimited fields using jq as follows:

$ cat file.txt | 
    jq -nR '[inputs | split(" ") | { "name": .[0], "street": .[1], "phone": .[2], "e-mail": .[3] }]'
[
  {
    "name": "alex",
    "street": "street1",
    "phone": "253465873",
    "e-mail": "alex123@google.com"
  },
  {
    "name": "john",
    "street": "street2",
    "phone": "442893646",
    "e-mail": "3jj33@google.com"
  },
  {
    "name": "kevin",
    "street": "street3",
    "phone": "125234763",
    "e-mail": "ke1vn@yahoo.com"
  }
]

Alternatively, for simple (non-nested) tabular data, you could use Miller

mlr --inidx --ojson --jvstack rename '1,name,2,street,3,phone,4,e-mail' file.txt
steeldriver
  • 81,074
  • Mainly out of curiosity: why -n and inputs? Your jq command seems to work without them too. – fra-san Oct 26 '20 at 14:50
  • @fra-san hmm good observation, tbh I don't know whether they're strictly equivalent or if there are other things going on under the hood with [inputs] – steeldriver Oct 26 '20 at 14:55
  • @steeldriver Sorry -- as roaima noted, the two commands (with or without -n and inputs) are not equivalent - the first one creates an array of n elements, the second one creates n single-element arrays. I somehow missed it, I'm deleting my comments here. – fra-san Oct 26 '20 at 15:05
  • @fra-san well your version may be closer to what the OP wants - let's see if they clarify expected output – steeldriver Oct 26 '20 at 15:08
0
$ column --table --separator=" " --table-columns name,street,phone,email --json test.txt

{
   "table": [
      {
         "name": "alex",
         "street": "street1",
         "phone": "253465873",
         "email": "alex123@google.com"
      },{
         "name": "john",
         "street": "street2",
         "phone": "442893646",
         "email": "3jj33@google.com"
      },{
         "name": "kevin",
         "street": "street3",
         "phone": "125234763",
         "email": "ke1vn@yahoo.com"
      }
   ]
}
  • You have to say what implementation of column you're using. I'm just getting column: illegal option -- - followed by usage: column [-tx] [-c columns] [-s sep] [file ...]. – Kusalananda Jan 24 '23 at 06:37
0

Using Miller (mlr) to convert the header-less and space-delimited data into JSON:

$ mlr --n2j label name,street,phone,e-mail file
{ "name": "alex", "street": "street1", "phone": 253465873, "e-mail": "alex123@google.com" }
{ "name": "john", "street": "street2", "phone": 442893646, "e-mail": "3jj33@google.com" }
{ "name": "kevin", "street": "street3", "phone": 125234763, "e-mail": "ke1vn@yahoo.com" }

The output is a separate JSON object per input record. The --n2j option is a shorthand for --inidx ("input is implicitly-integer-indexed (nidx)") in combination with --ojson ("output is JSON").

The label sub-command renames the fields in order.

Would you want to wrap the set of generated objects in an array, use --jlistwrap:

$ mlr --n2j --jlistwrap label name,street,phone,e-mail file
[
{ "name": "alex", "street": "street1", "phone": 253465873, "e-mail": "alex123@google.com" }
,{ "name": "john", "street": "street2", "phone": 442893646, "e-mail": "3jj33@google.com" }
,{ "name": "kevin", "street": "street3", "phone": 125234763, "e-mail": "ke1vn@yahoo.com" }
]
Kusalananda
  • 333,661
0

Try this awk command:

$ awk '{for (i=1;i<=NF;i++){$i="\""$i"\"";printf $i" "}};{printf"\n"}' infile

"alex" "street1" "253465873" "alex123@google.com" "john" "street2" "442893646" "3jj33@google.com" "kevin" "street3" "125234763" "ke1vn@yahoo.com"

dhm
  • 361