powershell escaping the escape character in a replace - string

Update - tried text without any back ticks still not replacing.
I have a file test.txt with these records:
name="BLUE_TBL_AC_EA_FREQ"` owner="BLUE_TBL_AC_EA_FREQ"
name="BLUE_TBL_AC_EA_FREQ" owner="RED_TBL_AC_EA_FREQ"
I would like to replace the string for the name attribute so I would use
name="BLUE_TBL_AC_EA_FREQ"
In the powershell script. This is what I did but the output file does not contain the replaced text, it is the same as the input.
Then I use a batch script that has this powershell command in the batch script
powershell -Command "(Get-Content "test.txt") | Foreach-Object {$_ -replace 'name="BLUE_TBL_AC_EA_FREQ"', 'name="BLUE_TBL_ACEAFREQ"'} | Set-Content "testo.txt""
The batch script does not replace the string that contains the string.
Am I doing something wrong, do I have to escape the double quotes for the string?
It is still not working for me.
End update
I am trying to use Powershell to replace some text in a file that makes use of the back tick.
In the file there is text such as
' name="BLUE_TBL_AC_EA_`FREQ"'
I would like to replace this text by
' name="BLUE_TBL_ACEAFREQ"'
The replace that I use in Powershell look like this
powershell -command "& {(Get-Content "file.txt") | Foreach-Object {$_ -replace ' name="BLUE_TBL_AC_EA_`FREQ"', ' name="BLUE_TBL_ACEAFREQ"'} | Set-Content "fileO.txt;}"
The ' name= is needed since there are multiple strings that contain the name="... string.
When I use this command nothing gets replaced. I have tried to escape the back tick by using a double back tick (``) and still nothing gets replaced.
I have searched and read many articles about Powershell and replacing text and the need for escaping characters. I thought I did what was needed but nothing gets replaced.
How do I replace the text that includes a back tick?

It looks like that when a replace is used in a batch script and the text contains either a back tick character or a double quote, then all the back ticks and the double quotes need to be escaped in the batch script.
The powershell command that was
powershell -Command "(Get-Content "test.txt") | Foreach-Object {$_ -replace 'name="BLUE_TBL_AC_EA_FREQ"', 'name="BLUE_TBL_ACEAFREQ"'} | Set-Content "testo.txt""
Becomes:
powershell -Command "(Get-Content "test.txt") | Foreach-Object {$_ -replace 'name=\"BLUE_TBL_AC_EA_FREQ\"', 'name=\"BLUE_TBL_ACEAFREQ\"'} | Set-Content "testo.txt""
If there is a back tick in the string then the back tick must be escaped as well using the reverse slash such as
\`
What a mess in a batch script.
Thanks for helping me figure this out.

I think your command have error that's why it is not changed. You missed the double quote after the txt, before the semicolon.
I tried this in my powershell and it is working.
(Get-Content "C:\test.txt") | Foreach-Object {$_ -replace ' name="BLUE_TBL_AC_EA_`FREQ"', ' name="BLUE_TBL_ACEAFREQ"'} | Set-Content "C:\test.txt"

Related

Issue finding and replacing regex in Powershell

I have an ini file that looks like this:
[list_text]
text_002=L-Win+3=Regards\nThomas
I try to find and replace the "\nThomas" with a different name:
$settings = Get-Content -Raw $path -Encoding UTF8
$settings = $settings -replace '`r`nThomas', '\nMike'
I tested different ways trying to find the "\nThomas" but nothing seems to work.
The pattern "`r`n..." will look for a literal carriage return and newline characters.
You aren't looking for any of those, you're looking for the verbatim escape sequence \n. To describe a backslash in a regex pattern, escape it with another backslash:
$settings -replace '\\nThomas', '\nMike'
You can also use [regex]::Escape() to escape any given verbatim string:
$settings -replace ([regex]::Escape('\nThomas')), '\nMike'

Powershell for Linux: Combining commands with pipe sign doesn't work

Any way to concatenate commands in Powershell for Linux?
This is what I'm trying to run:
pwsh -Command Invoke-ScriptAnalyzer -Path . | ConvertTo-Json | Out-File -FilePath "/home/administrator/scripts/test.json"
So, run the Invoke-ScriptAnalyzer, convert the results to Json and save the result to test.json.
It doesn't recognize anything after the | sign:
./test.sh: line 1: ConvertTo-Json: command not found
./test.sh: line 1: Out-File: command not found
I need this to go in a bash script, hence the need to launch pwsh with the -Command option.
Any ideas?
Thanks
As written, your | symbols are interpreted by your Linux shell (such as bash), not by PowerShell.
There are two soutions:
Preferably, quote the entire -Command argument (a '...' string in a POSIX-compatible shell such as bash uses the string's content verbatim):
pwsh -Command 'Invoke-ScriptAnalyzer -Path . | ConvertTo-Json | Out-File -FilePath "/home/administrator/scripts/test.json"'
Alternatively, individually \-escape all Linux-shell metacharacters that you want to pass through verbatim, such as \| and \" in this case:
pwsh -Command Invoke-ScriptAnalyzer -Path . \| ConvertTo-Json \| Out-File -FilePath \"/home/administrator/scripts/test.json\"
Note: In this case, pwsh receives multiple arguments after -Command. However, PowerShell simply joins them before interpreting the result as PowerShell code.
This differs from the command-line processing of POSIX-compatible shells, which interpret the first post--c argument as an implicit, ad-hoc script, with additional arguments getting passed as verbatim arguments to that script, accessible as usual as $1, ...

Powershell newline in script argument not working

I have this little script i use to call it with differernt RegEx arguments for replacing text in files:
param ($file, $fnd, $rpl)
(Get-Content $file -Raw) -replace $fnd , $rpl | Set-Content $file
problem is if i pass it an argument containing a new line escape code `r`n like so:
powershell -File txt-replace.ps1 "file path" "RegEx_pattern" "line1`r`nline2"
will write on file:
line1`r`nline2
instead of:
line1
line2
BUT IF i define $rpl inside the script, with the exact argument content, it works:
$rpl = "line1`r`nline2"
writes:
line1
line2
Also works if i run it as a command in widows terminal:
powershell -command "(Get-Content file_path | Out-String ).Trim() | ForEach-Object {$_ -replace 'RegEx_pattern' , \"line1`r`nline2\"} | Set-Content file_path "
i debugged it further inside the script:
write-host $rpl
writes in terminal:
line1`r`nline2
BUT
$rpl= "line1`r`nline2"
write-host $rpl
writes in terminal:
line1
line2
What am i missing?
It is simplest to just use -Command parameter.
powershell -Command ".\txt-replace.ps1 \"file path\" \"RegEx_pattern\" \"line1`r`nline2\""
The backslash escapes are for the CMD shell. Since you want those quotes passed to PowerShell, we need to escape them first at the CMD shell layer. Otherwise, CMD will think they are surrounding strings for it to interpret.
When using -File the script arguments are passed literally after interpretation by the current shell. CMD doesn't know what the newline characters are so they just remain `r`n and then are passed literally as one of the string arguments.
When using -Command, the command string is treated as if it were entered at a PowerShell prompt.
See About_PowerShell.exe for more information.

Using PowerShell sls (Select-String) vs grep vs findstr

Could someone clarify how sls (Select-String) works compared to grep and findstr?
grep: grep <pattern> files.txt
sls: sls <pattern> files.txt
(default parameter position for sls is pattern then file)
grep examples: grep "search text" *.log ; cat *.log | grep "search text"
sls examples: sls "search text" *.log ; cat *.log | grep "search text"
As an aside, all PowerShell Cmdlets are case-insensitive, unlike Linux tools which are generally always case-sensitive but also older tools like findstr which are case sensitive too, but findstr can be used in PowerShell, and works in situations where sls does not, for example: Get-Service | findstr "Sec" (this works without a problem!), but when we try to use sls in a similar way Get-Service | sls "Sec" we get nothing (presumably this fails because sls works with strings, but Get-Service returns an object, so that's understandable - but what is findstr doing then in that it can see the output as a string?).
So, my thinking is "ok, I need to make the output from Get-Service into a string to work with PowerShell Cmdlets", but that doesn't work (or not in a way that I would expect):
Get-Service | Out-String | sls "Sec" (gives results, but odd)
(Get-Service).ToString() | sls "Sec" (.ToString() just returns "System.Object[]")
How in general should I turn an object into a string so that it can manipulate the information (in the same way that Get-Service | findstr "Sec" can do so easily)?
Would appreciate if someone could clarify how things fit together in the above so that I can make more use of sls. In particular, Get-Service | Out-String | sls "Sec" does return stuff, just not the stuff I was expecting (is it searching for each character of "s" and "e" and "c" so is returning lots - that would not be very intuitive if so in my opinion)?
When you use Out-String by default, it turns the piped input object (an array of service objects in this case) into a single string. Luckily, the -Stream switch allows each line to be output as a single string instead. Regarding case-sensitivity, Select-String supports the -CaseSensitive switch.
# For case-insensitive regex match
Get-Service | Out-String -Stream | Select-String "Sec"
# For case-sensitive regex match
Get-Service | Out-String -Stream | Select-String "Sec" -CaseSensitive
# For case-sensitive non-regex match
Get-Service | Out-String -Stream | Select-String "Sec" -CaseSensitive -SimpleMatch
In either case, Select-String uses regex (use the -SimpleMatch switch to do a string match) to pattern match against each input string and outputs the entire string that matched the pattern. So if you only pipe into it a single string with many lines, then all lines will be returned on a successful match.
To complement AdminOfThings' helpful answer:
In order to find strings among the lines of the for-display string representations of non-string input objects as they would print to the console you indeed have to pipe to Out-String -Stream, whereas by default, simple .ToString() stringification is applied[1].
You shouldn't have to do this manually, however: Select-String should do it implicitly, as suggested in GitHub issue #10726.
Curiously, when piping to external programs such as findstr.exe, PowerShell already does apply Out-String -Stream implicitly; e.g:
Get-Date 1/1/2019 | findstr January works (in en-based cultures), because it is implicitly the same as Get-Date 1/1/2019 | Out-String -Stream | findstr January
By contrast, Get-Date 1/1/2019 | Select-String January is the equivalent of (Get-Date 1/1/2019).ToString([cultureinfo]::InvariantCulture) | Select-String January, and therefore does not work, because the input evaluates to 01/01/2019 00:00:00.
[1] More accurately, .psobject.ToString() is called, either as-is, or - if the object's ToString method supports an IFormatProvider-typed argument - as .psobject.ToString([cultureinfo]::InvariantCulture) so as to obtain a culture-invariant representation - see this answer for more information.

Powershell Delete String in text file

I have a file that I am downloading daily what I want to do is create a script that reads the text file and deletes out any lines containing the string "---"
I started with "(get-content L:\holdings.txt) | where {$_ -ne "" | out-file holdings.txt"
This deletes all the blank lines without any issue, I then tried
$del -like "*-*"
"(get-content L:\holdings.txt) | where {$_ -ne $del | out-file L:\holdings.txt"
Which I though would delete out any of the lines of data, whilst it runs without error the line is not being deleted out...
I don't know if it's relevant but the line I want to delete will always be the second line as it is a comma delimited SQL batch file automation.
The file reads as follows
Advice Num ,Bargain Number
--------------------,-----------------
Just to try and give you a graphical representation that I am trying to resolve
Any ideas?
Regards
Richard
Solved it, a quick amendment and here it is (get-content "L:\movement.txt") -notmatch "---" | out-file "L:\movement.txt"

Resources