I must replace a value in a file. This works for normal text with this command
(Get-Content $file) | Foreach-Object {$_ -replace "SEARCH", "REPLACE"} | Set-Content $file
But now, the search text is "$(SEARCH)" (without quotes). Backslash escaping the '$' with '`$' doesn't work:
(Get-Content $file) | Foreach-Object {$_ -replace "`$(SEARCH)", "BLA"} | Set-Content $file
Any ideas? Thank you.
The -replace operator is actually a regular expression replacement not a simple string replacement, so you've got to escape the regular expression:
(Get-Content $file) | Foreach-Object {$_ -replace '\$\(SEARCH\)', "BLA"} | Set-Content $file
Note that you can suppress string interpolation by using single quotes (') of double quotes (") around string literals, which I've done above.
Macintron,
You can try something like below :
(Get-Content $file) | Foreach-Object {$_.replace('$(SEARCH)', "BLA"} | Set-Content $file
slightly (or even more) faster
sc $file ((gc $file -Raw) -replace '\$\(search\)','BLAHH')
Related
(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!
'`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.
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
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' })
I have code in PowerShell and I need to replace letter $ for ;$ or insert ;
CSV file:
"11/23/2018 17:10:08"$"https://www.google.com"
"11/23/2018 17:10:20"$"https://www.yahoo.com"
And I need file:
11/23/2018 17:10:08;$https://www.google.com
11/23/2018 17:10:20;$https://www.yahoo.com
PS: Is it possible to find the titles to URLs?
(Get-Content C:\Users\user\Desktop\test\import.txt) |
Foreach-Object {$_ -replace '"'} |
Foreach-Object {$_ -replace "$", ';$'} |
Set-Content C:\Users\user\Desktop\test\export.txt
The wrong result is:
11/23/2018 17:03:46$https://www.seznam.cz;$
You need to escape $ since it has a special meaning in a regular expression (end of text).
(Get-Content C:\Users\user\Desktop\test\import.txt) |
Foreach-Object {$_ -replace '"'}|
Foreach-Object {$_ -replace "\$", ';$'} |
Set-Content C:\Users\user\Desktop\test\export.txt
It's an one-liner:
$inputFile = 'C:\test.txt'
$outputFile = 'C:\test1.txt'
[System.IO.File]::ReadAllLines($inputFile) | % { $_.Replace( '"$"', ';$' ).Trim('"') } | Out-File $outputFile
You can use multiple -replace in one command as follows:
(Get-Content C:\Users\user\Desktop\test\import.txt) |
Foreach-Object {$_ -replace '"' -replace '$', ';$'}|
Set-Content C:\Users\user\Desktop\test\export.txt
This script works, I want to condense it so if I add more lines to find and replace in the file I'm not being redundant.
Get-ChildItem C:\Users\JonSa\Desktop -Filter callcounts.xml | Foreach- Object{
(Get-Content $_.FullName) |
Foreach-Object {$_ -replace "#aXXXXX.ac1.vbspbx.com", ""} |
Set-Content $_.FullName
}
Get-ChildItem C:\Users\JonSa\Desktop -Filter callcounts.xml | Foreach- Object{
(Get-Content $_.FullName) |
Foreach-Object {$_ -replace "sip:", ""} |
Set-Content $_.FullName
}
I would like to accomplish this with fewer lines that leaves room for more arguments.
With only one file, don't use Get-ChildItem and a ForEach-Object
when using the -raw -parameter, you can apply the replace on the whole file
you can also append several -replace one after the other.
for the same replacement (here none) you can use an alternation | (OR)
an empty replacement can be omitted with the -replace operator (not so with the .replace() method)
$File = 'C:\Users\JonSa\Desktop\callcounts.xml'
(Get-Content $File -raw) -replace '#aXXXXX.ac1.vbspbx.com|sip:' |
Set-Content $File
I wrote this code to test out text manipulation. For each line read from my text file I replace tabs/returns/spaces, then I check if the line contains the carachters 'SAAS' and remove an A. I then write the content to an new file.
The issue is that the new file contains only lines that I made a replacement on and deletes any other lines of text from the orinal file when writing to the new file.
$Text = Get-Content -Path C:\Desktop\Phones\Phones_1.txt |
ForEach-Object {($_ -replace '\n','')} |
ForEach-Object {($_ -replace '\r','')} |
ForEach-Object {($_ -replace '\s','')} |
ForEach-Object {IF($_ | Select-String -Pattern 'SAAS'){$_ -replace 'SAAS','SAS'}}
$Text | Out-File 'C:\Desktop\Phones\phone2.txt'
Any help is appriciated.
It probably has to do with your Select-String function, which I don't believe needs to be there. Also, you can chain together replace statements greatly reducing the need to keep piping your code. I don't think it causes any issues, but you don't need to wrap your ForEach-Object blocks in braces either. Here's what that would look like:
$Text = Get-Content -Path C:\Desktop\Phones\Phones_1.txt |
ForEach-Object { $_ -replace '\n','' -replace '\r','' -replace '\s','' -replace 'SAAS','SAS' }
$Text | Out-File 'C:\Desktop\Phones\phone2.txt'
As $Text contains an array of single lines, replacing \r,\n is pretty useless.
You should provide an example of your input and expected output by editing your question.
Using a RegularExpression with lookarounds
(Get-Content .\Phones_1.txt -raw) -replace '\r|\n|\s|(?<=SA)A(?=S)'|Set-Content Phone2.txt
Yields this output from your above questions complete text:
Iwrotethiscodetotestouttextmanipulation.ForeachlinereadfrommytextfileIreplacetabs/returns/spaces,thenIcheckifthelinecontainsthecarachters'SAS'andremoveanA.Ithenwritethecontenttoannewfile.TheissueisthatthenewfilecontainsonlylinesthatImadeareplacementonanddeletesanyotherlinesoftextfromtheorinalfilewhenwritingtothenewfile.$Text=Get-Content-PathC:\Desktop\Phones\Phones_1.txt|ForEach-Object{($-replace'\n','')}|ForEach-Object{($-replace'\r','')}|ForEach-Object{($-replace'\s','')}|ForEach-Object{IF($|Select-String-Pattern'SAS'){$_-replace'SAS','SAS'}}$Text|Out-File'C:\Desktop\Phones\phone2.txt'Anyhelpisappriciated.
I have written the following code in powershell and I think there is a better way to replace strings in a given file
$(Get-content $output_file) -replace $regex2,'' | set-content $output_file
$(Get-content $output_file) -replace '_','(' | set-content $output_file
$(Get-content $output_file) -replace '"',')' | set-content $output_file
The first replace is for a regex - which is ok.
However in the second and third instances I'm replacing an "_" and replacing a "quote" with open and close parenthesis respectively.
Is there a cleaner way to write this code?
You can combine them to avoid reading and saving the file multiple times + easier to read (in my opinion). Ex:
(Get-content $output_file) -replace $regex2 -replace '_', '(' -replace '"', ')' | set-content $output_file