0

I am trying to get my head around RegEx and I have a variable I am trying to replace.

The variable is initialised as follows:

name = "" and I want a regex to replace the "" with "personName"

I have the following RegEx so far:

^(name).*?("")\2 which sets the capture groups and I have selected group 2 but I am not sure how to insert the replacement text.

Note: This will be used with sed in a script.

Luke
  • 603
  • 2
  • 11
  • 35
  • 1
    Could you please post sample input and sample output into your post too and let us know then? – RavinderSingh13 Sep 17 '18 at 10:49
  • Try `sed 's/^\(name *= *"\)"/\1NEW_TEXT_HERE"/g'` – Wiktor Stribiżew Sep 17 '18 at 11:00
  • There is no such thing as "A RegEx". There are BREs and EREs and PCREs and every tool implements some subset of those plus most tools have extensions and many tools also have delimiters you must handle/avoid and all tools either do or don't support capture groups. The regexp in your question appears to be trying to use a PCRE syntax and none of the standard UNIX tools support PCREs so YMMV. There are non-standard tools like perl and a GNU-specific version of grep that has a "highly experimental" `-P` option to support PCREs but no sed or awk supports PCREs. So - you need to know your tool! – Ed Morton Sep 17 '18 at 20:23
  • You should also become very familiar with [this quote](http://regex.info/blog/2006-09-15/247): `Some people, when confronted with a problem, think “I know, I'll use regular expressions.” Now they have two problems.`. The point is for any given problem there's always a clearer, simpler, etc. solution than using a complicated regexp. It sounds like you want to find a string and modify part of that string with another string - so maybe just do that instead of employing regexps and so avoid the associated complexity (see https://stackoverflow.com/q/29613304/1745001)? Post a [mcve] for help. – Ed Morton Sep 17 '18 at 20:31
  • @EdMorton It will be run as part of a Jenkins job that uses Terraform so it needs `sed` to run the replacement inline – Luke Sep 18 '18 at 09:18
  • @Luke Will the values you want to replace with contain chars like `&` or newlines? Or are they just alphanumeric? – Wiktor Stribiżew Sep 18 '18 at 10:57
  • @WiktorStribiżew The name is alphanumeric, the version parameter" the second one I havent added above, will be in the format 14.0, 13.2 etc – Luke Sep 18 '18 at 10:59
  • Ok, so you do not need any complex replacement code as described in [this question](https://stackoverflow.com/questions/29613304). You may accept my answer then. – Wiktor Stribiżew Sep 18 '18 at 11:00
  • @WiktorStribiżew This works in the shell, but not in a Jenkins Pipeline – Luke Sep 18 '18 at 11:01
  • You did not use it the way I did, you removed the backslashes from `(...)` and thus ruined the pattern. – Wiktor Stribiżew Sep 18 '18 at 11:01
  • Even with the backslashes it still errors in Jenkins – Luke Sep 18 '18 at 11:02
  • Ok, but this question is not about Jenkins, isn't it answered? – Wiktor Stribiżew Sep 18 '18 at 11:03
  • @Luke idk what `a Jenkins job that uses Terraform` means but I find it hard to believe that `sed` is the only tool you have available. Like `sed`, `awk` also comes as standard on all UNIX systems - don't you have that? When you say `run the replacement inline` do you mean work on piped input or do you mean update the original input file or something else? – Ed Morton Sep 18 '18 at 14:18
  • @EdMorton, Jenkins is a build server and Terraform is a server provisioning tool. I mean to replace in the original file, not piped input as I could use `awk` for that. – Luke Sep 19 '18 at 09:37
  • You can use awk to replace the original file too. If you're using `sed -i 'script'` then you're using GNU sed and so you also have GNU awk and then you can use `awk -i inplace 'script'`. With any awk or any other tool you can of course use `cmd 'script' file > tmp && mv tmp file` so it's never difficult to update a file whatever tool you use. – Ed Morton Sep 19 '18 at 13:16

1 Answers1

0

Here is how you may do that:

repl='NEW_VALUE'
sed "s/^\(name *= *\"\)\"/\1$repl\"/g" file > newfile

See the online demo.

Details of the BRE POSIX pattern:

  • ^ - start of a line (remove if the value may appear anywhere on a line)
  • \(name *= *\"\) - Capturing group 1: name, 0+ spaces, =, 0+ spaces, "
  • \" - a double quotation mark.

The \1 in the RHS inserts the value captured in Group 1 and $repl is interpolated with the variable value, then " is inserted.

g performs multiple search and replace.

In the current scenario, when all the replacement values are either alphanumeric or float numbers, the dynamic replacement does not need any special pre-processing. Otherwise, if the replacement strings can contain any chars, consider using these techniques.

Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • What if NEW_VALUE contained `&` or `\1` or `/` or a newline or...? See https://stackoverflow.com/q/29613304/1745001. – Ed Morton Sep 17 '18 at 20:29