dave0688
dave0688

Reputation: 5770

bash: Regex: Find and replace a variable in a file

I have a bash script which should find a regex match in a file, and replace it's content.

So what I have in the file it's this (it's a version string in a package.json):

// ...
"version": "1.2.13",
  "repository": {
    "type": "git"
  },
// ...

Now I want to match the number (the 13), increase it and replace it with the current one. What I have so far is a solution with awk, which doesn't work.

awk -v lvar="$VAR" '/version":\s"[0-9]+.[0-9]+.([0-9]+)/{print $0}' ${PACKAGE_JSON_PATH}

echo ${lvar}

The pattern works so, it gives me the last number. However, the awk statement doesn't work.

The output looks like this:

"version": "1.2.13",

So what it does: It prints the entire line. But, I just want the 13 out of that. And, it doesn't save it into the lvar variable.

Sorry, I'm quite new to this bash stuff :)

Upvotes: 2

Views: 650

Answers (2)

oliv
oliv

Reputation: 13249

You'd better use jq rather than awk to parse JSON file.

Assuming you file is:

$ cat file
{ "version": "1.2.13",
  "repository": {
    "type": "git"
   }
}

The following command replaces the version value by incrementing the last number of the version string. That'll work with a 3 or more number in the string.

<file jq '.version=([(.version | split(".")[0:-1][]),(.version | split(".")[-1]|tonumber +1|tostring)]|join("."))'
{
  "version": "1.4.5.14",
  "repository": {
    "type": "git"
  }
}

Upvotes: 0

Ed Morton
Ed Morton

Reputation: 203645

To replace 13 with 14 (or any number with the next number), using GNU awk (which I see you're already using since you have \s in your script) for the 3rd arg to match():

$ awk 'match($0,/(^\s*"version":.*\.)([0-9]+)(.*)/,a) {$0 = a[1] a[2]+1 a[3]} 1' file
// ...
"version": "1.2.14",
  "repository": {
    "type": "git"
  },
// ...

You COULD just print the original value if you like:

$ awk 'match($0,/(^\s*"version":.*\.)([0-9]+)(.*)/,a) {print a[2]}' file
13

but I suspect you're trying to do that because you're thinking about your real problem the wrong way and trying to solve it with a shell script instead of an awk script.

Upvotes: 1

Related Questions