Martin Backasch
Martin Backasch

Reputation: 1899

How to replace $(data) in a string?

I have a configuration file named configuration.xml and it looks like:

<?xml version="1.0" encoding="utf-8" ?>
<Configuration xmlns="http://tempuri.org/Configuration.xsd">

  <Icons>
    <Icon name="about" file="$(data)\more\data\about.png" />
    <Icon name="help" file="$(data)\more\data\help.png" />
  </Icons>

</Configuration>

For deploying these configuration file to different environments, I want to use a powershell script (currently PowerShell 5.1), which should replace the $(data) with the real path - environment\path\to\data.

A short version of my script looks like:

$file = Get-Item '.\configuration.xml'
    
$content = ($file | Get-Content)

# file="$(data)\more\data" => file="environment\path\to\data\more\data"
$content = $content -replace '$(data)', 'environment\path\to\data'

$content | Set-Content $file.FullName

I tried to escape the $ using single quotes and also tried to escape it with double quotes by using a backtick "`$(data)" but this does not work.

Also trying to solve it with using unicode "$([char]0x0024)(data)" was not successful.

Can somebody point me to a solution?


Side note
I would like to change $(data), but it is part of a 3rd party library, which I can't change. The 3rd party library uses $(data) to replace the path, and this path is configured in another file. In most cases it is use full, but in this particular use case I have to configure it for some instances/sub configurations with the full path.

Upvotes: 1

Views: 63

Answers (1)

AdminOfThings
AdminOfThings

Reputation: 25021

When using -replace operator, regex is used to match a string. The regex matched string is replaced by a literal string with some exceptions. The general syntax is below:

$strings -replace $regex,$stringliteral

The regex must follow the regex escape rules rather than PowerShell escape rules. The regex escape character is \. Since $() are special characters in regex, your regex expression would need to be \$\(data\). This can be done automatically for you through the regex Escape() method.

$file = Get-Item '.\configuration.xml'

$content = ($file | Get-Content)

$content = $content -replace [regex]::Escape('$(data)'), 'environment\path\to\data'

$content | Set-Content $file.FullName

Upvotes: 4

Related Questions