Powershell newline in script argument not working - string

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.

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, ...

File content into windows variable - PowerShell

I'm new in PowerShell, I want to put the content of a file into a windows variable.
In fact I need the equivalent of those linux commans on windows
testvar=$(cat test.txt)
echo $testvar
Actually, because cat and echo are aliased to Get-Content and Write-Output respectively, that code will work, though you need to prefix testvar with a $, so it reads $testvar. It can also be written with proper cmdlets and remove the unnecessary subexpression:
$testvar = Get-Content test.txt
Write-Output $testvar
And you really don't need to use Write-Output, either. simply writing $testvar on its own will default to the output stream.
$testvar = Get-Content "test.txt"
Write-Host $testvar
cat is an alias in powershell to Get-Content,
echo is an alias to Write-Output

powershell escaping the escape character in a replace

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"

Unix sed command is not replacing the supplied string

I am writing a shell script in which I have to separate the file name and file path from a complete file path. For example /home/loneranger/Documents/test/file.dat is the complete path. I want to separate name and Path and put them in variables. So far I am able to separate file name by using basename command.
file_name =$(basename $path)
file_location =`echo $path | sed 's/$file_name//' `
But the sed command is not working. It's working when I execute it outside in command line by replacing the file_name by file.dat. Not sure why it's behaving this way. Can somebody explain.
PS: Sorry for poor formatting as I am typing from a mobile device.
the tool dirname does what you want:
file_name=$(basename $path)
file_location=$(dirname $path)
the sed command is not working because bash does not expand variables inside single quotes.
sed 's/$file_name//'
^ single quote
^ variable inside single quote not expanded
either use double quotes or open the single quotes around the variable:
sed "s/$file_name//"
sed 's/'$file_name'//'
but as said the tool dirname does what you want.
also note that you may not put spaces around the equal sign in the variable assignment
file_name =$(basename $path)
^ there should be no space here
the line above does not assign the result of basename to the variable file_name. instead it will try to execute the command file_name with one parameter which is the result of basename.
file_name=$(basename $path)
^ no space here
this line will define the variable.
It isn't working because you use $file_name in simple quote ('). Use double quotes " for enable variable translation.
file_location =`echo $path | sed "s/$file_name//"

Resources