1

Following are the contents of the config file

{
  "Line1": true,
  "Line2": "\/\/{hostname}\/",
  "version": "2.8.9",
  "Line4": true,
  "Line5": true
}

I am using Linux, and I need to find semantic version number 2.8.9 above and store in one variable and replace it with either major, minor or patch version based on the logic in the next variable.

Can someone please suggest the appropriate sed regex expression for both finding and replacing the semantic version

These are 2 valid regex expressions for semantic versions

  1. ^([0-9]+\.){2,2}(\*|[0-9]+)(\-.*){0,1}$
  2. ^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$
2
  • 3
    Seems like JSON ,isn't it? Jan 23, 2023 at 15:28
  • 1
    Advice to newcomers: If an answer solves your problem, please accept it by clicking the large check mark (✓) next to it and optionally also up-vote it (up-voting requires at least 15 reputation points). If you found other answers helpful, please up-vote them. Accepting and up-voting helps future readers. Jan 23, 2023 at 15:48

2 Answers 2

1

Ways to parse JSON

Disclaimer, was reading to fast, this is not a search&replace response.

@Kusulandra gave the good one:

jq --arg new '3.0.0' '.version = $new' file | sponge file

With :

jq -r '.version' file.json

With gron and GNU

gron file.json | grep -oP 'version.*?"\K[^"]+'

With

package main
import (
   "encoding/json"
   "fmt"
   "io/ioutil"
   "log"
   "os"
)

func main() {
   fileContent, err := os.Open("/tmp/file.json")

   if err != nil {
      log.Fatal(err)
      return
   }

   defer fileContent.Close()

   byteResult, _ := ioutil.ReadAll(fileContent)

   var res map[string]interface{}
   json.Unmarshal([]byte(byteResult), &res)

   fmt.Println(res["version"])
}

With json_xs command line

json_xs < file.json -t none -e 'print %{ $_ }{version}'

Installed via Perl module JSON::XS

With

#!/usr/bin/perl
use strict; use warnings;

use File::Slurp;
use JSON::XS;

my $text = read_file("file.json");
$text = decode_json $text;
print $text->{version};

with

import json

# Opening JSON file
f = open('file.json')

# returns JSON object as a dictionary
# by parsing the data and assigns it to a variable
data = json.load(f)

# print the json value 'version'
print(data['version'])

# Closing file
f.close()

Output

2.8.9
3
  • 1
    Replacing with jq+sponge: jq --arg new '3.0.0' '.version = $new' file | sponge file
    – Kusalananda
    Jan 23, 2023 at 16:45
  • Thanks Gilles for your solution, however i need to read the json version from the bash file and replace it using regex and sed (unless some command can achieve it) Jan 23, 2023 at 16:50
  • @VikasArora This is what Gilles is showing. Parsing a JSON file is best done with a JSON-aware tool, such as the most excellent jq utility, or with some library, like what Gilles is showing.
    – Kusalananda
    Jan 24, 2023 at 10:23
0

If you are only after the version number then grep could do a better job than sed:

$ grep -o '[0-9]\+\.[0-9]\+\.[0-9]+' infile 
2.8.9

But if you are looking to find and replace the version number then try this:

$ sed 's/[0-9]\+\.[0-9]\+\.[0-9]\+/REPLACEMENT/' infile 

{
  "Line1": true,
  "Line2": "\/\/{hostname}\/",
  "version": "REPLACEMENT",
  "Line4": true,
  "Line5": true
}
2
  • thanks dhm for the solution. This works till single digit numbers like 2.8.9, but fall short when any of the numbers goes to double digit. Can you please modify this command in order to handle something like 2.10.11 Jan 24, 2023 at 8:38
  • Modified as requested.
    – dhm
    Jan 24, 2023 at 10:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .