Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I replace a line in a file using PowerShell?

Tags:

powershell

I am trying to read replace a line in a configuration file using PowerShell. Sometimes this script works, but most of the time it does not replace the line.

(Get-Content D:\home\App_Config\Sitecore.config) `     | %{ $_ -replace '  <setting name="Media.MediaLinkServerUrl" value=" "/>',' <setting name="Media.MediaLinkServerUrl" value="https://newurl.com"/>'} `     | Set-Content D:\home\App_Config\Sitecore.config 
like image 531
neha Avatar asked Nov 18 '16 14:11

neha


People also ask

How do I replace a line in PowerShell?

In PowerShell we can use the Replace() method on any string or variable that is a string. The method needs two arguments, the text or character that you want to find and the with what you want to replace it with.

How do you replace text in PowerShell?

Using the Replace() Method The replace() method has two arguments; the string to find and the string to replace the found text with. As you can see below, PowerShell is finding the string hello and replacing that string with the string hi . The method then returns the final result which is hi, world .

Can PowerShell edit text files?

PowerShell can be used to perform different windows operations, such as creating folders, directories. Similarly, text files can also be handled using PowerShell; we can edit text files to append or remove the content from the text files.


1 Answers

Try the following:

$file = 'D:\home\App_Config\Sitecore.config' $regex = '(?<=<setting name="Media\.MediaLinkServerUrl" value=")[^"]*' (Get-Content $file) -replace $regex, 'https://newurl.com' | Set-Content $file 

* Re Set-Content: In Windows PowerShell it uses your system's legacy single-byte character encoding by default (based on the active ANSI code page), so you may want to use -Encoding to control the output file's encoding explicitly; PowerShell [Core] 6+ defaults to BOM-less UTF-8.

  • Also note the required (...) around the Get-Content call to ensure that the pipeline can write back to the same file that Get-Content has read from.
  • If there's a chance that the opening tag in question (<setting ...>) spans multiple lines, use
    Get-Content -Raw $file (PSv3+) to read the entire file content as a single string (thanks, deadlydog);
    without -Raw, Get-Content returns an array of strings, representing the input lines.

Due to using a regular expression to match your existing setting, any text currently inside value="..." is matched, so this command will work even when run repeatedly.

By contrast, what you tried uses an effective literal (... value=" ") to find what to replace, and after the 1st - successful - run, that literal no longer matches, and subsequent runs have no effect.

The command above uses a streamlined approach to replacement:

  • (?<=<setting name="Media.MediaLinkServerUrl" value=") is a look-behind assertion ((?<=...)) that matches, but doesn't capture what it matches: it finds the part up to and including the opening " of the value you're trying to replaces, without making that prefix a part of what will get replaced.

  • [^"]* then matches the entire value, up to, but not including the closing ". ([^"] is a character set that matches any character other than (^) a ", and * finds any (possibly empty) sequence of such characters.

  • Therefore, because the regex captured only the value itself, all you need to specify as the replacement string is the new value.

like image 145
mklement0 Avatar answered Sep 20 '22 21:09

mklement0