leeand00 leeand00 - 24 days ago 8
JSON Question

Add an empty line prior to another matched line in jq?

Say I have a raw input like the following:

"```"
"include <stdio.h>"
"..."
"```"
"''some example''"
"*bob"
"**bob"
"*bob"


And I'd like to add a blank line right before the "*bob":

"```"
"include <stdio.h>"
"..."
"```"
"''some example''"
""
"*bob"
"**bob"
"*bob"


Can this be done with jq?

Answer Source

Here is another solution which uses the -s (slurp) option

.[: .[["*bob"]][0]] + ["\n"] + .[.[["*bob"]][0]:] | .[]        

that's a little unreadable but we can make it better with a few functions:

  def firstbob:  .[["*bob"]][0] ;
  def beforebob: .[: firstbob ] ;
  def afterbob:  .[ firstbob :] ;

    beforebob + ["\n"] + afterbob
  | .[]

if the above filter is in filter.jq and the sample data is in data then

$ jq -Ms -f filter.jq data

produces

"```"
"include <stdio.h>"
"..."
"```"
"''some example''"
"\n"
"*bob"
"**bob"
"*bob"

One issue with this approach is that beforebob and afterbob won't quite work as you probably want if "*bob" is not in the input. The easiest way to address that is with an if guard:

    if firstbob then beforebob + ["\n"] + afterbob else . end
  | .[]

with that the input will be unaltered if "*bob" is not present.