I'm looking to change the value of a key in a json file
Example:
"House":"sample.house.city"
Need to change the word "sample" to something else.
I can do this with:
sed -i 's|sample.house.city|town-home.house.city|g' file.json
but there is no guarantee that "sample" is going to be the same every time.
I've tried:
sed -i 's|*.house.city|town-home.house.city|g' file.json
but it doesn't change.
Also tried:
sed -i 's|"*.house.city"|"town-home.house.city"|g' file.json
but that ends up like:
"sample"town-home.house.city"
Any recommendations on how to do this correctly?
CodePudding user response:
To match any word, you can use [[:alnum:]_]*
(POSIX BRE) / [[:alnum:]_]
(POSIX ERE):
sed -i 's|[[:alnum:]_]*\.house\.city|townhome.house.city|g' file.json
See the online demo:
#!/bin/bash
s='"House":"sample.house.city"'
sed 's|[[:alnum:]_]*\.house\.city|townhome.house.city|g' <<< "$s"
Output:
"House":"townhome.house.city"
Note you also need to escape dots that are used to match literal dots.
CodePudding user response:
Explanation
1st Capturing Group (\w )
- \w matches any word character (equivalent to [a-zA-Z0-9_])
- matches the previous token between one and unlimited times, as many times as possible, giving back as needed (greedy)
2nd Capturing Group (.house.city)
- \. matches the character .
- house matches the characters house literally (case sensitive)
- \. matches the character .
- city matches the characters city literally (case sensitive)
Global pattern flags
- g modifier: global. All matches (don't return after first match)
\2 replace with the 2nd Captured Group (.house.city)
$ sed -E 's/(\w )(\.house\.city)/town-home\2/g' <<< '"House":"sample.house.city"'
"House":"town-home.house.city"
$ sed -iE 's/(\w )(\.house\.city)/town-home\2/g' file.json