0

(I have read the other threads with similar names...)

I'm new to PowerShell. I am trying to understand how to find and replace newlines. For example, find double newlines and replace them with a single or vice versa.

I have a test document that was created using Notepad:

The quick brown fox jumped over the lazy dog
The quick brown fox jumped over the lazy dog

The quick brown fox jumped over the lazy dog
The quick brown fox jumped over the lazy dog

I am working in the PowerShell ISE for testing/learning.

When I run the following command (attempting to replace one newline with two):

((Get-Content -path $filename -raw) -replace '`n','`n`n') | Set-Content -path $filename
Get-Content -path $filename -raw

The output is unchanged. So I tried the following and it remained unchanged.

((Get-Content -path $filename -raw) -replace '`r`n','`r`n`r`n') | Set-Content -path $filename

So, knowing that PowerShell uses a back-tick rather than a backslash, but out of frustration, I tried the following command:

((Get-Content -path $filename -raw) -replace '\n','\n\n') | Set-Content -path $filename

And, surprisingly (to me), all of the newlines were replaced, but with the string literal '\n\n'. So it seems searching for a newline worked with a backslash but not with a back-tick. The replacement, unfortunately, was the literal string rather than the CRLF I need.

I'm stumped. But for what it's worth, I also tried the following and the string literal was again used for the replacement (i.e., in place of newlines, the document contained '`r`n').

((Get-Content -path $filename -raw) -replace '\n','`r`n') | Set-Content -path $filename

I have seen many posts where people were mistakenly using a backslash, but in my case it seems like a backslash is required for the search, and I don't understand what is required to replace a newline.

Thanks!

3
  • 5
    Use double-quotes for the escape sequence: "`r`n" Commented Jun 30, 2019 at 20:59
  • '`n' just matches the literal characters [backtick][n], which isn't what you want. You want to interpolate those values. For that, you'll need to use double quotes i.e., '`n' should be "`n". Commented Jun 30, 2019 at 21:08
  • Just to add, the reason '\n' was able to successfully match the newlines is because the -replace operator uses regular expression for the matching and \n is regex for newline. If you want to do a replace without matching based on regex, you can use the .replace() method instead. Commented Jun 30, 2019 at 22:38

3 Answers 3

3

'`n' just matches the literal characters [backtick][n], which isn't what you want. You want to interpret those values. For that, you'll need to use double quotes i.e., '`n' should be "`n". According to Microsoft...

The special characters in PowerShell begin with the backtick character, also known as the grave accent (ASCII 96). ... These characters are case-sensitive. The escape character is only interpreted when used within double quoted (") strings.

Sign up to request clarification or add additional context in comments.

Comments

1

Use double quotes. You probably also want the -nonewline option to set-content, so that another `r`n doesn't get put at the end of the file.

PS> '`n'
`n
PS> "`n"



PS> (Get-Content -path $filename -raw) -replace "`n","`n`n" | 
      Set-Content -path $filename -nonewline

Comments

1

There are several ways of doing this. First one is to read the file as a single string and perform a regex -replace on it: Remember that on Windows machines the Newline is a combination of two characters CR ('\r', ASCII value 13) and LF ('\n', ASCII value 10).

$filename = 'D:\test.txt'

# replace single newlines by a double newline
$replaceWith = '{0}{0}' -f [Environment]::NewLine
(Get-Content -Path $filename -Raw) -replace '\r?\n', $replaceWith | Set-Content -Path 'D:\test-to-double.txt' -Force

# replace double newlines by a single newline
$replaceWith = [Environment]::NewLine
(Get-Content -Path $filename -Raw) -replace '(\r?\n){2}', $replaceWith | Set-Content -Path 'D:\test-to-single.txt' -Force

Another way is to read in the file as string array (let PowerShell deal with single newlines):

# read the file as string array and join the elements with a double newline
$replaceWith = '{0}{0}' -f [Environment]::NewLine
(Get-Content -Path $filename) -join $replaceWith | Set-Content -Path 'D:\test-to-double.txt' -Force

# read the file as string array and join the elements with a single newline
$replaceWith = [Environment]::NewLine
(Get-Content -Path $filename) -join $replaceWith | Set-Content -Path 'D:\test-to-single.txt' -Force

The latter method is also extremely suited for removing empty or whitespace-only lines before you 'normalize' the newlines in the text: In that case, just replace (Get-Content -Path $filename) with (Get-Content -Path $filename | Where-Object { $_ -match '\S' })

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.