I have a json file that needs to be updated on a certain condition.
Sample json
{ "Actions" : [ { "value" : "1", "properties" : { "name" : "abc", "age" : "2", "other ": "test1" } }, { "value" : "2", "properties" : { "name" : "def", "age" : "3", "other" : "test2" } } ] }
I am writing a script that makes use of Jq to match a value and update, as shown below
cat sample.json | jq '.Actions[] | select (.properties.age == "3") .properties.other = "no-test"'
Output (printed to terminal)
{ "value": "1", "properties": { "name": "abc", "age": "2", "other ": "test1" } } { "value": "2", "properties": { "name": "def", "age": "3", "other": "no-test" } }
While this command makes the needed change, it outputs the entire json on the terminal and does not make change to the file itself.
Please advise if there is an option to have jq make changes on the file directly (similar to sed -i).
By default, sed reads the file line by line and changes only the first occurrence of the SEARCH_REGEX on a line. When the replacement flag is provided, all occurrences are replaced. INPUTFILE - The name of the file on which you want to run the command.
The s command (as in substitute) is probably the most important in sed and has a lot of different options. The syntax of the s command is ' s/ regexp / replacement / flags '.
Substitution command In some versions of sed, the expression must be preceded by -e to indicate that an expression follows. The s stands for substitute, while the g stands for global, which means that all matching occurrences in the line would be replaced.
This post addresses the question about the absence of the equivalent of sed's "-i" option, and in particular the situation described:
I have a bunch of files and writing each one to a separate file wouldn't be easy.
There are several options, at least if you are working in a Mac or Linux or similar environment. Their pros and cons are discussed at http://backreference.org/2011/01/29/in-place-editing-of-files/ so I'll focus on just three techniques:
One is simply to use "&&" along the lines of:
jq ... INPUT > INPUT.tmp && mv INPUT.tmp INPUT
Another is to use the sponge
utility (part of GNU moreutils
):
jq ... INPUT | sponge INPUT
The third option might be useful if it is advantageous to avoid updating a file if there are no changes to it. Here is a script which illustrates such a function:
#!/bin/bash function maybeupdate { local f="$1" cmp -s "$f" "$f.tmp" if [ $? = 0 ] ; then /bin/rm $f.tmp else /bin/mv "$f.tmp" "$f" fi } for f do jq . "$f" > "$f.tmp" maybeupdate "$f" done
instead of sponge
:
cat <<< $(jq 'QUERY' sample.json) > sample.json
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With