0

I have a text file like this,

Name: john 
...some random characters
Title: Dev
...some random characters
Country: Iceland
...some random characters
Name: randy
...
Title: Professor
...
Country: Greenland
...

I am looking for a way to convert this into json like this,

{
Name: john,
Title: Dev,
Country: Iceland
},
{
Name: randy,
Title: Professor,
Country: Greenland
}

There's always one line of extra random characters between each important line.

I am kind of new to bash and having a hard time figuring out how to do this so I was hoping if someone here could help me.

I tried this command but didn't work,

jq -Rs '[ split("\n")[] | select(length > 0) | split(":") | {Name: .[0], Title: .[1], Country: .[2]}]' text.txt
RickK24
  • 7
  • 5

3 Answers3

1

In your paricular case it can be achieved with awk:

#!/usr/bin/env bash

awk -F':' '{ if ($1=="Name")  {name=$2}
             if ($1=="Title") {title=$2}
             if ($1=="Country") {print "{\nName:"name",\nTitle:"title",\nCountry:"$2"\n},"}
           }' | head -c -2
echo

(head and echo are used here to deal with unnecessary comma at the end.)

Example:

$ ./txt2json.sh <data.txt
{
Name: john,
Title: Dev,
Country: Iceland
},
{
Name: randy,
Title: Professor,
Country: Greenland
}
Doj
  • 1,244
  • 6
  • 13
  • 19
1

Assuming the keys "Name", "Title" and "Country" appear in order, how about a solution combining awk and jq:

awk '
    BEGIN {FS=": *"; OFS=":"}
    /^Name:/ {name=$2}
    /^Title:/ {title=$2}
    /^Country:/ {print(name,title,$2)}
' text.txt | jq -Rs 'split("\n")[] | select(length > 0) | split(":") | {Name: .[0], Title: .[1], Country: .[2]}'

Output:

{
  "Name": "john",
  "Title": "Dev",
  "Country": "Iceland"
}
{
  "Name": "randy",
  "Title": "Professor",
  "Country": "Greenland"
}
tshiono
  • 21,248
  • 2
  • 14
  • 22
1

This is an ed solution that is only tested on the GNU variant but since you're on ubuntu then this should work.

Given the file named file.txt and it's content.

Name: john
xxxsome random characters
Title: Dev
xxxsome random characters
Country: Iceland
xxxsome random characters
Name: randy
xxx
Title: Professor
xxx
Country: Greenland
xxx
Name: Foo
xxxx
Title: Anyone
xxxx
Country: FarFarAway
xxxx

The script

#!/bin/sh

ed -s file.txt <<'EOF'
v/^Name:\|^Title:\|^Country:/d
,s/^\(.*[^:]*\): \(.*\)/"\1": "\2"/
g/Name\|Title/s/$/,/
,s/^/   /
g/Country/t. \
s/.*/},/g
1,$-1g/}/t. \
s/.*/{/g
0a
{
.
$s/,//
,p
Q
EOF

Output

{
   "Name": "john",
   "Title": "Dev",
   "Country": "Iceland"
},
{
   "Name": "randy",
   "Title": "Professor",
   "Country": "Greenland"
},
{
   "Name": "Foo",
   "Title": "Anyone",
   "Country": "FarFarAway"
}
  • Change Q to wq from the sh script to edit the file.txt in-place.

  • To make the argument/file not hard coded to the script, change file.txt to "$1" then you can call the script like (assuming the script name is myscript

./myscript file.txt
Jetchisel
  • 7,493
  • 2
  • 19
  • 18