Ilkay Isik
Ilkay Isik

Reputation: 213

find and replace a value in a json file using bash

I have several .json files similar to this.

{
    "AcquisitionNumber": 1,
    "TotalReadoutTime": 0.035,
    "IntendedFor": "func/sub-02_task-rest_run-01_bold.nii.gz"
}

I want to change the sub number in the "IntendedFor" line using a bash variable, looping over different subs.For example if sub is 03:

sub=03
echo $sub
03

How can I change the value of sub-02 to sub-03 using this bash variable?

Upvotes: 0

Views: 8199

Answers (4)

oguz ismail
oguz ismail

Reputation: 50750

Use :

jq --arg sub "$sub" '.IntendedFor |= sub("(?<=sub-)[^_]+"; $sub)' file

See this online example

Note that your jq binary must be compiled with regex support in order to use sub function.

And, you can implement inline editing using a for loop and temporary files:

sub=03

for jsonfile in *.json; do
    tempfile=$(mktemp -u)
    jq --arg sub "$sub" '.IntendedFor|=sub("(?<=sub-)[^_]+";$sub)' "$jsonfile" > "$tempfile"
    mv "$tempfile" "$jsonfile"
done

Upvotes: 6

Ljm Dullaart
Ljm Dullaart

Reputation: 4969

There are better ways of doing this, but there is a bash-solution:

#!/bin/bash
fromstring="sub-02"
tostring="sub-03"

while read line; do
    case "$line" in
    (*IntendedFor*) echo $(line/$fromstring/$tostring) ;;
    (*)  echo $line ;;
    esac
 done < JSONfile

Upvotes: 0

peak
peak

Reputation: 116690

Using sponge (part of moreutils):

for f in *.json; do
  jq --arg sub "$sub" '.IntendedFor |= sub("/sub-[^_]+";"/sub-"+$sub)' "$f" | sponge "$f"
done

In any case, a simple regex suffices.

sponge for Windows

See:

Upvotes: 1

Cyrus
Cyrus

Reputation: 88583

With jq and bash:

value=$(jq -r '.IntendedFor' file)
new_value="${value/sub-02/sub-03}"
jq --arg new "$new_value" '.IntendedFor |= $new' file

Output:

{
  "AcquisitionNumber": 1,
  "TotalReadoutTime": 0.035,
  "IntendedFor": "func/sub-03_task-rest_run-01_bold.nii.gz"
}

Upvotes: 2

Related Questions