Boyd
Boyd

Reputation: 451

jq to replace array key values from file

I have a json file with this data:

{
  "data": [                                                                                                                                      
    {
      "name": "table",    
      "values": [    
        "This is old data",    
        "that needs to be",    
        "replaced."    
      ]    
    }    
  ]    
}    

But my challege here is I need to replace that values array with words in a text or csv file:

this
this
this
is
is
an
an
array

My output needs to have (although I could probably get away with the words all on one line...):

      "values": [
        "this this this",
        "is is",
        "an an",
        "array"    
      ],

Is this possible with only jq? Or would I have to get awk to help out? I already started down the awk road with:

awk -F, 'BEGIN{ORS=" "; {print "["}} {print $2} END{{print "]"}}' filename

But I know there is still some work here...

And then I came across jq -Rn inputs. But I haven't figured out how or if I can get the desired result.

Thanks for any pointers.

Upvotes: 1

Views: 1045

Answers (2)

dawg
dawg

Reputation: 103744

You can use jq and awk.

Given:

$ cat file
{
    "data": [                                                         
        {
            "name": "table",
            "values": [ 
                "This is old data",
                "that needs to be",
                "replaced."
            ]    
        }    
    ]    
}


$ cat replacement
this
this
this
is
is
an
an
array

First create a string for the replacement array (awk is easy to use here):

ins=$(awk '!s {s=last=$1; next}
     $1==last{s=s " " $1; next} 
     {print s; s=last=$1}
     END{print s}' replacement | tr '\n' '\t')

Then use jq to insert into the JSON:

jq --rawfile txt <(echo "$ins") '.data[].values |= ( $txt | split("\t")[:-1] )' file 
{
  "data": [
    {
      "name": "table",
      "values": [
        "this this this",
        "is is",
        "an an",
        "array"
      ]
    }
  ]
}

You can also use ruby to process both files:

ruby -r json -e '
    BEGIN{ ar=File.readlines(ARGV[0])
                .map{|l| l.rstrip}
                .group_by{|e| e}
                .values
                .map{|v| v.join(" ")}
        j=JSON.parse(File.read(ARGV[1]))
    }   
    j["data"][0]["values"]=ar
    puts JSON.pretty_generate(j)' txt file

   # same output...

Upvotes: 1

Inian
Inian

Reputation: 85550

Assuming you have a raw ASCII text file named file and an input JSON file, you could do

jq --rawfile txt file '.data[].values |= ( $txt | split("\n")[:-1] | group_by(.) | map(join(" ")) )' json

produces

{
  "data": [
    {
      "name": "table",
      "values": [
        "an an",
        "array",
        "is is",
        "this this this"
      ]
    }
  ]
}

Upvotes: 3

Related Questions