Doug Bergh
Doug Bergh

Reputation: 153

jq to replace multiple occurrences of a character only in a section of only certain lines of a json file

I have a set of files containing sections like the following:

    "billing_date": {
        "type": "date",
        "meta": {
            "display": "Billing Date",
            "format": ":%x"
        }
    },
    "billing_accounting_date": {
        "type": "date",
        "meta": {
            "display": "Billing Accounting Date",
            "format": ":%x"
        }
    }

I need to change the contents of the "display" field to use underscores instead of spaces, so the result is like this (note underscores in Billing_Date and Billing_Accounting_Date):

    "billing_date": {
        "type": "date",
        "meta": {
            "display": "Billing_Date",
            "format": ":%x"
        }
    },
    "billing_accounting_date": {
        "type": "date",
        "meta": {
            "display": "Billing_Accounting_Date",
            "format": ":%x"
        }
    }

Pierre Francois kindly suggested using jq; I've been trying that but still haven't been able to put it all together.

Each of several files have several dozen different fields; I've been able to extract the replacements I need but don't see how to put them back into a file.

% jq '.mappings.properties[].meta.display' input.txt                                                                               
"Key"
"Action"
"Transaction Import Time"
"Hash"
"Data Exchange 1.0 Warnings"
"Data Exchange 1.0 Errors"
"Effective Time"
"Import ID"
"Import S3 Key"
"Importing User Name"
"Utility UUID"
"Utility Name"
"Import File Row"
"Account ID"
"Location ID"
"Service Point ID"
"Meter ID"
"Bill ID"
"Register Number"
"Billing Unit Of Measure"
"Billing Cycle Start Date"
"Billing Cycle End Date"
"Billing Cycle Start Read"
"Billing Cycle End Read"
"Billing Cycle Consumption"
"Billing Date"
"Billing Accounting Date"

% jq '.mappings.properties[].meta.display | sub(" "; "_") | sub(" "; "_") | sub(" "; "_") | sub(" "; "_")' input.txt               
"Key"
"Action"
"Transaction_Import_Time"
"Hash"
"Data_Exchange_1.0_Warnings"
"Data_Exchange_1.0_Errors"
"Effective_Time"
etc...

Upvotes: 2

Views: 1646

Answers (1)

peak
peak

Reputation: 116977

The following jq filter can be used to achieve the desired result in a single invocation of jq:

.billing_date.meta.display |= gsub(" "; "_")
| .billing_accounting_date.meta.display |=  gsub(" "; "_")

Or maybe this is what you want:

.mappings.properties[].meta.display |= gsub(" "; "_") 

If you are willing to take the risk to overwrite the input file, you might like to use the sponge utility from "coreutils".

Using walk

You might also wish to consider using walk, e.g. along the lines of:

walk(if type == "object" and has("display") then .display |= gsub(" "; "_") else . end)

Upvotes: 3

Related Questions