PowerShell 2.0 command equivalent to PowerShell 3.0 Get-Content -Raw - powershell

I am currently working on a code snippet to convert AS3 files to JS.
Below is my script.
$source = "sample.as"
$dest = "modifiedScript.js"
$raw1 = Get-Content -Path $source | Out-String
$raw1 -replace "extends.*?({)", '{' | Set-Content $dest
Sample.as:
class EquivalentFraction extends MainClass
{
// other codes
function f1(){
}
}
I am trying to get the output like this (replace whatever comes between extends and { by {):
class EquivalentFraction
{
// other codes
function f1(){
}
}
The above code does not work if the opening brace is present in next line.
As I am using PowerShell 2.0, I am unable to use Get-Content -Raw to get the contents without lines.
After searching, I came to know that I have to use Out-String instead of -Raw switch.
But it's not working.

The PowerShell v2 equivalent for Get-Content -Raw is Get-Content | Out-String. The reason why your code doesn't do what you expect has nothing to do with the data import.
You don't get the expected result because of the regular expression you're using. . matches any single character except newlines. Since your data has the opening curly bracket on the line after the line with the extends keyword you do have a newline between extends and {, meaning that extends.*?({) will never match.
You can resolve this by using [\s\S] (match any whitespace and any non-whitespace)
$raw1 -replace 'extends[\s\S]*?{', '{'
or by using the "single line mode" option (which makes . match newlines as well)
$raw1 -replace '(?s)extends.*?{', '{'

Related

Concating $_ in Pattern for regular expression in PowerShell

I want to use the $_ in a Pattern in Powershell. I have the following script but it doesn't work
Get-Content ..\myfile.txt | ForEach-Object {
$counter=(gc *.log | Select-String -Pattern '$_\/Directory\/Cars\/Sign.jpg')
}
If I run the script, in lines of the myfile.txt which I know there is some ocurrences according to the Pattern it finds 0, so how I must write the $_ in the pattern?.
Thanks so much
The reason PowerShell isn't expanding $_ is because you're using a verbatim string literal (a string literal defined using ' single-quotes).
For an expandable string literal, you need to use " double-quotes - PowerShell will then attempt to expand variable expressions inside the string:
Get-Content ..\myfile.txt | ForEach-Objet {
$counter=(gc *.log | Select-String -Pattern "${_}/Directory/Cars/Sign\.jpg")
}
Note: ${_} is the same variable as $_.
The explicit {} qualifiers prevents PowerShell from interpreting something that isn't actually part of the variable name as such. Let's say your pattern looked like "$_Sign\.jpg", PowerShell would attempt to resolve the token $_Sign instead of just $_, whereas "${_}Sign\.jpg" makes it obvious to PowerShell's parser where the variable expression ends.
Depending on what myfile.txt contains, you might want to escape the input string:
Get-Content ..\myfile.txt | ForEach-Object {
$counter=(gc *.log | Select-String -Pattern "$([regex]::Escape($_))/Directory/Cars/Sign\.jpg")
}
For further reading on these topics, peruse the about_Quoting_Rules and about_Regular_Expressions help topics

Select-String successfully finds a string, replacing that found string with something else fails

uniquefile1.txt is a file that has no carriage returns (if it matters) and is very long. I am trying to match a variety of patterns.
The text file is not open when the program runs.
I visually have checked that the file has my pattern exactly as
written, when using Select-String it confirms that the pattern
exists.
When I go to replace, if I do Out-Host and search my
output in my ide it does not show that it has changed. It is not
replacing this string, and I do not know what I am doing wrong.
There are no errors of any kind when running my code.
I have tried:
$file = Get-Content C:\Uniqueline1
$file.Replace($variableforpattern1, $varForReplacement) | Set-Content Uniquefile1.txt
As well as the above except with the actual strings in place of the variables.
$file = Get-Content C:\uniquefile1.txt -Raw
$SEL = Select-String -Path "C:\uniquefile1.txt" -Pattern ">>>11^A"
if ($SEL = $true)
{
write "true"
}
else
{
write "not true"
}
$file -replace ">>>11^A", ">>>0111^A" | Set-Content "C:\uniquefile1.txt"
AdminOfThings was correct, please see their comment. This character ^ has special meaning in Regex and must be escaped.
-replace uses regex for the search pattern and therefore must have regex-special characters escaped if they are to be matched literally. The \ is used for escaping.
$file = Get-Content C:\uniquefile1.txt -Raw
$file -replace '>>>11\^A', '>>>0111^A' | Set-Content C:\uniquefile1.txt
Select-String without the -SimpleMatch switch uses regex as well. I don't know how that ever matched for you if the -replace operation failed.

Replacing String without replacing whole content of file powershell

Trying to edit this line of a file ("VoIP.Enabled "1"). I wanna change the 1 to a zero. When I change it with
$dewprefs = Get-Content .\dewrito_prefs.cfg
$dewprefs | Select-String "VoIP.Enabled" | ForEach-Object {$_ -replace "1","0"} | Set-Content .\dewrito_prefs.cfg}`
However when I use this script, it removes 100 other lines, edits the right line, then deletes everything else, just leaving the line I wanted to edit.
Any help on this matter would be highly appreciated
Select-String acts as a filter: that is, the input it is given is only passed out if it matches a pattern.
Therefore, only the line of interest is written to the output file.
Do not use Select-String if all input lines - though possibly modified - should be passed through; use only ForEach-Object, and conditionally modify each input line:
$dewprefs = Get-Content .\dewrito_prefs.cfg
$dewprefs |
ForEach-Object { if ($_ -match 'VoIP\.Enabled') { $_ -replace '1', '0' } else { $_ } } |
Set-Content .\dewrito_prefs.cfg
$_ -match 'VoIP\.Enabled' now does what Select-String did in your original command: it matches only if the input line at hand contains literal VoIP.Enabled (note how the . is escaped as \. to ensure that is treated as a literal in the context of a regular expression).
Note how both branches of the if statement produce output:
$_ -replace '1', '0' outputs the result of replacing all instances of 1 in the input line with 0
$_ simply passes the input line through as-is.
Most likely you could replace the if statement with a single -replace expression, however, and, assuming that the file is small enough to be read as a whole (quite likely, in the case of a configuration file), you can use a variant of Stu's helpful simplification.
Taking full advantage of the fact that -replace supports regexes (regular expressions), the code can update lines based on a key name such as VoIP.Enabled only, without needing to know that key's current value.
$key = 'VoIP.Enabled'
$newValue = '1'
# Construct a regex that matches the entire target line.
$regex = '^\s*' + [regex]::Escape($key) + '\b.*$'
# Build the replacement line.
$modifiedLine = "$key $newValue"
(Get-Content .\dewrito_prefs.cfg) -replace $regex, $modifiedLine | Set-Content .\dewrito_prefs.cfg
Note that writing the output back to the input file only works because the input file was read into memory as a whole, up front, due to enclosing the Get-Content call in (...).
This will work too, with PowerShell v3+, and is a little more succinct:
(Get-Content .\dewrito_prefs.cfg).replace('"VoIP.Enabled "1"', '"VoIP.Enabled "0"') |
Set-Content .\dewrito_prefs.cfg
Your quotes are a little strange (3 double quotes in total?), I've mimicked what you've asked, however.

powershell multiple block expressions

I am replacing multiple strings in a file. The following works, but is it the best way to do it? I'm not sure if doing multiple block expressions is a good way.
(Get-Content $tmpFile1) |
ForEach-Object {$_ -replace 'replaceMe1.*', 'replacedString1'} |
% {$_ -replace 'replaceMe2.*', 'replacedString2'} |
% {$_ -replace 'replaceMe3.*', 'replacedString3'} |
Out-File $tmpFile2
You don't really need to foreach through each replace operations. Those operators can be chained in a single command:
#(Get-Content $tmpFile1) -replace 'replaceMe1.*', 'replacedString1' -replace 'replaceMe2.*', 'replacedString2' -replace 'replaceMe3.*', 'replacedString3' |
Out-File $tmpFile2
I'm going to assume that your patterns and replacements don't really just have a digit on the end that is different, so you might want to execute different code based on which regex actually matched.
If so you can consider using a single regular expression but using a function instead of a replacement string. The only catch is you have to use the regex Replace method instead of the operator.
PS C:\temp> set-content -value #"
replaceMe1 something
replaceMe2 something else
replaceMe3 and another
"# -path t.txt
PS C:\temp> Get-Content t.txt |
ForEach-Object { ([regex]'replaceMe([1-3])(.*)').Replace($_,
{ Param($m)
$head = switch($m.Groups[1]) { 1 {"First"}; 2 {"Second"}; 3 {"Third"} }
$tail = $m.Groups[2]
"Head: $head, Tail: $tail"
})}
Head: First, Tail: something
Head: Second, Tail: something else
Head: Third, Tail: and another
This may be overly complex for what you need today, but it is worth remembering you have the option to use a function.
The -replace operator uses regular expressions, so you can merge your three script blocks into one like this:
Get-Content $tmpFile1 `
| ForEach-Object { $_ -replace 'replaceMe([1-3]).*', 'replacedString$1' } `
| Out-File $tmpFile2
That will search for the literal text 'replaceMe' followed by a '1', '2', or '3' and replace it with 'replacedString' followed by whichever digit was found (the '$1').
Also, note that -replace works like -match, not -like; that is, it works with regular expressions, not wildcards. When you use 'replaceMe1.*' it doesn't mean "the text 'replaceMe1.' followed by zero or more characters" but rather "the text 'replaceMe1' followed by zero or more occurrences ('*') of any character ('.')". The following demonstrates text that will be replaced even though it wouldn't match with wildcards:
PS> 'replaceMe1_some_extra_text_with_no_period' -replace 'replaceMe1.*', 'replacedString1'
replacedString1
The wildcard pattern 'replaceMe1.*' would be written in regular expressions as 'replaceMe1\..*', which you'll see produces the expected result (no replacement performed):
PS> 'replaceMe1_some_extra_text_with_no_period' -replace 'replaceMe1\..*', 'replacedString1'
replaceMe1_some_extra_text_with_no_period
You can read more about regular expressions in the .NET Framework here.

String replacement not working in powershell script at runtime

I have powershell file in which i have line of variable decalration as below
[string] $global:myExePath = "\\myshare\code\scripts";
I want to replace \\myshare\code\scripts with \\mynewshare\code1\psscript at runtime by executing a powershell script.
I am using
Get-Content $originalfile | ForEach-Object { $_ -replace "\\myshare\code\scripts", $mynewcodelocation.FullName } | Set-Content ($originalfile)
If am execuing
{ $_ -replace "scripts", $mynewcodelocation.FullName } it is working fine, but it is not working for { $_ -replace "\\myshare\code\scripts", $mynewcodelocation.FullName }
What is wrong here ?
'\' is a special regex character used to escape other special character.You need to double each back slash to match one back slash.
-replace "\\\\myshare\\code\\scripts",$mynewcodelocation.FullName
When you don't know the content of a string you can use the escape method to escape a string for you:
$unc = [regex]::escape("\\myshare\code\scripts")
$unc
\\\\myshare\\code\\scripts
-replace $unc,$mynewcodelocation.FullName