Search code examples
powershellvariablesreplacenewline

How to replace text with different text, a newline and a variable in powershell?


I am trying to find a specific word (find) and replace it with itself but add a newline and some other text via a variable after it like:

find
new text

My code looks like this:

powershell -command "$file=(gc file.txt);$var=(gc value.txt);$null=new-item -force $file -value ((gc -encoding utf8 $file) -replace ('find',$var) | out-string)"

How do I add the word find and a newline to the replacement?


Solution

  • In PowerShell code:

    -replace 'find', "`$0`n$var"
    
    • $0 in the substitution operand of the regex-based -replace operator refers to what the regex specified as the first operand matched.

    • Note: $0 is equivalent to $&, and even though the latter is more frequently used, the use of $0 is deliberate - see below.

    • Due to use of an expandable (double-quoted) string ("..."), the $ of the $0 placeholder must be escaped as `$ in order to be passed through to the .NET regex engine (which is the one processing such placeholders.

    • "`n" is an escape sequence that expands to a LF-only newline; use "`r`n" for a Windows-format CRLF newline, or $([Environment]::NewLine) for the platform-native newline format.

    • $var embeds the (stringified) value of this variable in the resulting string

      • Note: (gc value.txt) (Get-Content value.txt) potentially returns multiple strings, namely one for each line, which are collected in an array. Stringifying such an array inside "..." turns it into a single-line representation, with the elements separated with spaces. Use Get-Content -Raw to read a multi-line file as a whole (though you may then want to trim a trailing newline).

    In the context of your PowerShell CLI call, from outside PowerShell:

    Replace -replace ('find',$var) with:

    -replace 'find', \"`$0`n$var\"
    

    Note:

    • " chars. must be \-escaped in order for PowerShell's command-line processing to preserve them as part of the code to subsequently execute.

    • The above would not work if $& were used in lieu of $0 when calling from cmd.exe / a batch file, because the & character would run afoul of cmd.exe's parsing.

      • There are workarounds for cases where use of & (or other cmd.exe metacharacters, such as ^ and |) inside an embedded double-quoted string is a must - see this answer.