2

I have a string like:

schedule="0.25"

and I want to replace the 0.25 lets say with 0.50

I could achieve this with:

sed 's/\"....\"/\"0\.50\"/g'

the problem is I don't know the value between the double quotes, and therefore I do not know the length. It could be any value, but it will be always preceded by schedule=.

  • It depends... you might try something like sed 's/\"[^"]*\"/\"0.50\"/g'(this matches 0 or more characters that aren't '"' between '"' for replacement). – vonbrand Aug 11 at 20:37
  • @vonbrand this is pretty much what steeldriver suggested in his answer... (apart from the escapes). – nath Aug 11 at 22:31
6

You can use [^"]* to match a sequence of zero or more non-" characters. So

$ echo 'schedule="0.25"' | sed 's/"[^"]*"/"0.5"/'
schedule="0.5"
4

It looks like you just want to replace whatever comes after the equal sign with "0.50". This is easily done with awk:

$ echo 'schedule="0.25"' | awk -F = 'BEGIN { OFS=FS } $1 == "schedule" { $2 = "\"0.50\"" } { print }'
schedule="0.50"

The awk program looks specifically for a record whose 1st =-delimited field is schedule. When found, it replaces the second field with "0.50".

If 0.50 is variable, you may pass this value into the awk script like this:

$ newval=0.222
$ echo 'schedule="0.25"' | awk -v nv="$newval" -F = 'BEGIN { OFS=FS } $1 == "schedule" { $2 = sprintf("\"%s\"", nv) } { print }'
schedule="0.222"

And obviously, if schedule may vary as well,

$ newval=0.222
$ variable=schedule
$ echo 'schedule="0.25"' | awk -v v="$variable" -v nv="$newval" -F = 'BEGIN { OFS=FS } $1 == v { $2 = sprintf("\"%s\"", nv) } { print }'
schedule="0.222"

With sed, you could just ignore whatever comes after the = and replace it with whatever you wish:

$ echo 'schedule="0.25"' | sed 's/=.*/="0.50"/'
schedule="0.50"

To make sure we replace only the value for schedule, and not some other setting's value,

$ echo 'schedule="0.25"' | sed '/^schedule=/s/=.*/="0.50"/'
schedule="0.50"

This puts a condition on our substitution; The line must have the string schedule= at the start of it for it to trigger.

We could even insert shell variables into our sed expression, but be aware that we must make sure that the values of these variables do not break the sed syntax (by containing characters that affect the matching or the delimiting of the commands):

$ newval=0.222
$ variable=schedule
$ echo 'schedule="0.25"' | sed "/^$variable=/s/=.*/=\"$newval\"/"
schedule="0.222"

As opposed to the awk example, here we rely on the shell to inject the values of our variables into the sed editing script. This would normally be classified as a code injection vulnerability in the cases where the values of the variables are not under our control (like when we are reading them from a user supplied source).

1

If you are invoking sed/awk from a bash script/terminal, then you could avoid using the external tools and take advantage of bash's own string processing capabilities:

$ a='schedule="0.25"'
$ echo "$a"
schedule="0.25"
$ b="${a/\"*/\"0.50\"}"
$ echo "$b"
schedule="0.50"
  • 1
    Shorter: b="${a/\"*/\"0.50\"}". Note that you're using filename globbing patterns here, not regular expressions, so your * just matches the rest of the string anyway. A standard compliant variation would be b="${a%%=*}"'="0.50"'. – Kusalananda Aug 11 at 8:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.