PowerShell, regex, Replace things that are not - powershell

Using PowerShell I want to replace everything in a line in the file myFile.txt that is quoted in parenthesis that is not ("Sally") with ("Admin"). Is this the right way to do so, or is there a more appropriate way?
(Get-Content .\myFile.txt) -replace '\(\"(?!Sally).*\"\)', '("Admin")' | Set-Content .\myFile.txt
The contents of myFile.txt is:
("Bob")
("Sally")
("Tom")
And I'd like it to be:
("Admin")
("Sally")
("Admin")

Related

Editing a text file inside PowerShell Script

I made a Powershell script to update my mpv scripts. One of them being this
https://raw.githubusercontent.com/mpv-player/mpv/master/player/lua/osc.lua
I want the script to edit and remove all instances of show_message(get_playlist(), 3) from the file.
I tried (get-content .\Scripts\osc.lua) | foreach-object {$_ -replace "show_message(get_playlist(), 3)", ""} | Out-File .\Scripts\osc.lua and (get-content .\portable_config\Scripts\osc.lua) | foreach-object {String.Replace [RegEx]::Escape('show_message(get_playlist(), 3)'),''} | Out-File .\portable_config\Scripts\osc.lua but they dont seem to work.
Basically I want the script to automatically download osc.lua(which works fine as intended) and then remove all instances of show_message(get_playlist(), 3) from the file. My PowerShell version is 5.1.
You can use the following with the Replace Operator:
$regex = [regex]::Escape('show_message(get_playlist(), 3)')
(Get-Content .\Scripts\osc.lua) -replace $regex |
Set-Content .\Scripts\osc.lua
Alternatively, you can use the String.Replace method from the String class, which does not use regex.
(Get-Content .\Scripts\osc.lua).Replace('show_message(get_playlist(), 3)','') |
Set-Content .\Scripts\osc.lua
Explanation:
When using the -replace operator, the matching mechanism is a regex match. Certain characters are metacharacters for regex and must be escaped before they can be interpreted literally. In this case ( and ) need to be escaped. You can either do that manually with \ (\( and \)) or use the Escape() method from the Regex class. From the code above, you can type $regex after its declaration and see how it was escaped.
When replacing a string with an empty string, you do not need to specify a replacement string. 'String' -replace 'ing' has the same results as 'String' -replace 'ing',''
Note: You are mixing Get-Content and Out-File in your code without using the -Encoding parameter. It is possible you could output a different encoding than the original file. If this matters to you, I'd suggest using the -Encoding parameter with the appropriate encoding.

Batch File to Find and Replace in text file using whole word only?

I am writing a script which at one point has to check in a text file and remove certain strings. So far I have this:
powershell -Command "(gc myFile.txt) -replace 'foo', 'bar' | Out-File -encoding ASCII myFile.txt"
The only problem is that that can find and replace but will not remove the line all together.
The second problem is that say I am removing the line that has Mark, it needs to not remove a line that has something like Markus.
I don't know if this is possible with the powershell interface?
Your current code will only replace foo with bar, this is what replace does.
Removing the whole line if it matches requires a different approach, almost backwards, as you can use notmatch to output any lines that do not match you filter - effectively removing them.
Also using regex word boundaries will then only match Mark but not Markus:
(Get-Content file.txt) | Where-Object {$_ -notmatch "\bMark\b"} | Set-Content file.txt

Matching lines in file from list

I have two text files, Text1.txt and Text2.txt
Text2.txt is a list of keywords, one keyword per line. I want to read from Text1.txt and any time a keyword in the Text2.txt list shows up, pipe that entire line of text to a new file, output.txt
Without using Text2.txt I figured out how to do it manually in PowerShell.
Get-Content .\Text1.txt | Where-Object {$_ -match 'CAPT'} | Set-Content output.txt
That seems to work, it searches for "CAPT" and returns the entire line of text, but I don't know how to replace the manual text search with a variable that pulls from Text2.txt
Any ideas?
Using some simple regex you can make a alternative matching string from all the keywords in the file Text2.txt
$pattern = (Get-Content .\Text2.txt | ForEach-Object{[regex]::Escape($_)}) -Join "|"
Get-Content .\Text1.txt | Where-Object {$_ -match $pattern} | Set-Content output.txt
In case your keywords have special regex characters we need to be sure they are escaped here. The .net regex method Escape() handles that.
This is not an efficient approach for large files but it is certainly a simple method. If your keywords were all similar like CAPT CAPS CAPZ then we could improve it but I don't think it would be worth it depending how often the keywords change.
Changing the pattern
If you wanted to just match the first 4 characters from the lines in your input file that is just a matter of making a change in the loop.
$pattern = (Get-Content .\Text2.txt | ForEach-Object{[regex]::Escape($_.Substring(0,4))}) -Join "|"

How can I remove CRLF if anywhere between double quotes, using PowerShell?

My text file looks like this.
"MikeCRLF","","","Dell","DevelCRLFCRLFoper"CRLF
"SuCRLFsan","","","Apple","ManagCRLFer"CRLF
Desired result:
"Mike","","","Dell","Developer"LF
"Susan","","","Apple","Manager"LF
I tried this on PowerShell:
"C:\Users\abc\Desktop\1.txt"
(Get-Content $path -Raw).Replace("`r`n","`n") | Set-Content $path -Force
When I do this, I don't get the desired result. Also, I am left with one CRLF at the end. I don't want that either.
Please tell me how to do this using PowerShell v3.
This method avoids checking to see if \r\n is in quotes. Instead, it tries to find the "real" end of line situations and converts those first. Then it just purges the rest.
(Get-Content test.txt -Raw) -replace '([^,]")(\s*\r\n\s*)+("[^,])',"`$1`n`$3" -replace '\r\n',''
I think this should handle most of the stuff you throw at it, but let me know if you find a special case.
edited to fix the replacement string
If you are using the PowerShell Community Extensions, you can use the ConvertTo-UnixLineEnding command e.g.:
ConvertTo-UnixLineEnding C:\users\abc\desktop1.txt -dest desktop1-converted.txt -Enc ascii

Powershell. How to join two separately consecutive strings in one string in file?

I have a file. I need to select some consecutive strings, join them and put them in the file on place first of selected strings in powershell script
I try:
$test=cat $file |select-string -pattern '<DIV>$' -Context 0,1|%{$_ -split "\r\n"}
$t= -join ($test[0],$test[1])
cat $file|%{$_ -replace '$test','$t'} > temp.txt
or this
cat $file | %{$_ -replace '<DIV>[\u000d\u000a]{0,2}',""}>temp.txt
but fail
From what you show as code, I conclude you want to remove line feeds after a div tag.
cat, as an alias of get-content returns an array, so line feeds are reset by array output to file.
There are certainly strict powershel cmdlets ways of doing it.
The fastest I found is:
[io.file]::readAllText("$file") -replace "<DIV>`r`n" "<DIV>" > temp.txt
readAlltext keeps the line feeds of the file, so the replace works.
HTH