Inserting text in the middle of a line with AWK

Maybe I was not searching for the right terms but I had a bit of hard time to find how to this on the internet. Most of the solutions are about writing either in the line above or below the target line. I wanted to write text on the middle of a JSON object. Bear in mind I ain’t no AWK or SED wizard, I just started using AWK and there is probably far more efficient ways of doing this, I just couldn’t find them.

Suppose we have the following JSON object (filename blabla.json):

{"_id": "10", "data": {"entities": {"adequate rise": 1, "thermal neutrality": 2, "domain boundary": 2}}}

I wanted to insert an extra element in the root of the object called filename, containing the file name. The following awk command solves my problem:

$ awk -F"{" 'BEGIN{OFS="{";}{for(i=1; i < NF; i++) if(i==1) printf "%s\"filename\": \"%s\", ",OFS, FILENAME; else printf "%s",$i OFS; if (NF) printf "%s",$NF; printf ORS}' blabla.json

{"filename": "blabla.json", "_id": "10", "data": {"entities": {"adequate rise": 1, "thermal neutrality": 2, "domain boundary": 2}}}

I’ll try to break it down:

  •  The -F option is used to set the field separator, by default the string separator is set to  white spaces but in this case we want the separator to be “{“, we went to insert our text just after the first “{” so that is going to help us.
  • By partitioning the line into different fields using “{” we will obtain the following fields: “
  • $1 = "", $2="_id": "10", "data":" $3="entities": " $4=""adequate rise": 1, "thermal neutrality": 2, "domain boundary": 2}}}"
  • BEGIN{OFS=”{“;} this command initialises the OFS (Output field separator) to “{“. We will use the OFS to reprint our line.
  • We start the command with a loop over all the fields “for(i=1; i < NF; i++)”.  NF is the number of fields
  • “if(i==1) printf “%s\”filename\”: \”%s\”,  “,OFS, FILENAME; else printf “%s”,$i OFS;” In the loop, we check if we are in the first field (the place were we actually want to insert the field) and use the printf function to insert the OFS (“{“) and FILENAME which is a predefined variable in awk containing the filename. If we are not in the first field (the else part) we simply print the field followed by the OFS.
  • “if (NF) printf “%s”,$NF; printf ORS}” when we reach the last field (NF), we print it together with the ORS (Output Record Separator) which is newline by default

Now as you see this is pretty complicated, but if you know another way of doing this in a simpler way please leave a comment below, I’ll be glad to hear it.

2 thoughts on “Inserting text in the middle of a line with AWK

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s