Sed – Replace Value to Use Quotes Where Needed

sedtext processing

I have 100+ jinja template files with 0-k occurrences of "value: …" string in each of them. The problem is that some of the files are using:

value: something

some of them:

value: 'something'

and some of them:

value: "some other thing"

I need all of these to look the same, to use double quotes. I thought I'd do it with sed:

sed -i 's/value: ['"]?(.*)['"]?/value: "\1"/g' *.j2

but as you can see I'm quite horrible with sed and the past 2 hours only made me want to break my keyboard with the nonsense error messages I'm getting, like: unterminated `s' command and such.

Sample input:

- param:
  name: Command
  type: String
  value: '/bin/echo'
- param:
  name: Args
  type: String
  value: Hello World
- param:
  name: Something
  type: EnvVar
  value: "PATH"

from this I need to get:

- param:
  name: Command
  type: String
  value: "/bin/echo"
- param:
  name: Args
  type: String
  value: "Hello World"
- param:
  name: Something
  type: EnvVar
  value: "PATH"

Best Answer

When you need to use the two forms of quotes ("') in the expression, things get tricky. For one, in your original attempt the shell identifies this 's/value: [' as a quoted string: the latter quote is not preserved.

In these cases, rather than having a headache, you can simply put the Sed commands in a file. Its contents won't be subject to the shell manipulation.

quotes.sed:

# (1) If line matches this regex (value: '), 
# (2) substitute the first ' with " and
# (3) substitute the ' in the end-of-line with ".
/value: '/{
  s/'/"/
  s/'$/"/
}
# (4) If line matches this regex (value: [^"]), 
# (5) substitute :<space> for :<space>" and
# (6) append a " in the end-of-line.
/value: [^"]/{
  s/: /: "/
  s/$/"/
}
$ sed -Ef quotes.sed file
- param:
  name: Command
  type: String
  value: "/bin/echo"
- param:
  name: Args
  type: String
  value: "Hello World"
- param:
  name: Something
  type: EnvVar
  value: "PATH"
Related Question