How to replace square brackets in powershell *[* - powershell

i want to replace a square bracket in powershell, to change the title.
my code:
if($finaltitlewithouterrors -like "*`[*`]") {
$finaltitlewithouterrors=$finaltitlewithouterrors.Replace("[", '')
}
i tried other schemas but none of them work, like
if($finaltitlewithouterrors -like "*`[*") {
$finaltitlewithouterrors=$finaltitlewithouterrors.Replace("`[", '')
}
i also tried it with
*``[*
i found a similar question (https://stackoverflow.com/questions/54094312/how-do-i-use-square-brackets-in-a-wildcard-pattern-in-powershell-get-childitem#:~:text=Square%20brackets%20can%20be%20used%20as%20a%20wildcard,and%20consequently%20the%20support%20in%20Powershell%20is%20spotty.)
but noting of it work.
for example i have a name called:
BatmanTheDarkNight[1].pdf
and the final name should look like:
BatmanTheDarkNight.pdf
or
BatmanTheDarkNight1.pdf

You need to escape the square bracket [ ] characters when using -replace. Here is a rough solution using [regex]::Escape
$fileName = "BatmanTheDarkNight[1].pdf"
$newFileName = $fileName -replace [Regex]::Escape("["), "" `
-replace [Regex]::Escape("]"), ""
$newFileName
BatmanTheDarkNight1.pdf
Note the use of a backtick to chain -replace operations on the next line.

Just use the regex -replace for this:
$finaltitlewithouterrors = 'BatmanTheDarkNight[1].pdf' -replace '[\[\]]'
# --> BatmanTheDarkNight1.pdf
Regex details:
[\[\]] Match a single character present in the list below
A [ character
A ] character

Related

Replace string with line break with another string in Powershell

I want to replace
$fieldTool.GetFieldValue($i
tem,"Title")
with
{{(sc_get_field_value i_item 'Title')}}
The original string has a line break and I am using 'n like this $fieldTool.GetFieldValue($i'ntem,"Title")
This is the code
$template = '<div class="tile-inspiration__title field-title">$fieldTool.GetFieldValue($i
tem,"Title")</div>'
$matchString = '$fieldTool.GetFieldValue($i'ntem,"Title")'
$pattern = $([regex]::escape($matchString))
$replaceString = "{{(sc_get_field_value i_item 'Title')}}"
$newtemplate = $template -replace $pattern, $replaceString
Write-Host $newtemplate
The above code is not working. How can I replace the string with line break with another string.
Any suggestion would be appreciated.
Thanks in advance
To replace newlines, you should use regex pattern \r?\n. This will match both *nix as well as Windows newlines.
In your template string however, there are multiple characters that have special meaning in regex, therefore you need to do [regex]::Escape(), but that also would wrongfully escape the characters \r?\n, rendering it as \\r\?\\n, so adding that in the $matchString before escaping it, would be of no use.
You can manually first replace the newline with a character that otherwise is not present in the $matchString and has no special meaning in regex.
$template = '<div class="tile-inspiration__title field-title">$fieldTool.GetFieldValue($i
tem,"Title")</div>'
# for demo, I chose to replace the newline with an underscore
$matchString = '$fieldTool.GetFieldValue($i_tem,"Title")'
# now, escape the string and after that replace the underscore by the wanted \r?\n pattern
$pattern = [regex]::escape($matchString) -replace '_', '\r?\n'
# $pattern is now: \$fieldTool\.GetFieldValue\(\$i\r?\ntem,"Title"\)
$replaceString = "{{(sc_get_field_value i_item 'Title')}}"
# this time, the replacement should work
$newtemplate = $template -replace $pattern, $replaceString
Write-Host $newtemplate # --> <div class="tile-inspiration__title field-title">{{(sc_get_field_value i_item 'Title')}}</div>

add quotation mark to a text file powershell

I need to add the quotation mark to a text file that contains 500 lines text.
The format is inconsistent. It has dashes, dots, numbers, and letters. For example
1527c705-839a-4832-9118-54d4Bd6a0c89
16575getfireshot.com.FireShotCaptureWebpageScreens
3EA2211E.GestetnerDriverUtility
I have tried to code this
$Flist = Get-Content "$home\$user\appfiles\out.txt"
$Flist | %{$_ -replace '^(.*?)', '"'}
I got the result which only added to the beginning of a line.
"Microsoft.WinJS.2.0
The expected result should be
"Microsoft.WinJS.2.0"
How to add quotation-mark to the end of each line as well?
There is no strict need to use a regex (regular expression) in your case (requires PSv4+):
(Get-Content $home\$user\appfiles\out.txt).ForEach({ '"{0}"' -f $_ })
Array method .ForEach() processes each input line via the script block ({ ... }) passed to it.
'"{0}"' -f $_ effectively encloses each input line ($_) in double quotes, via -f, the string-format operator.
If you did want to use a regex:
(Get-Content $home\$user\appfiles\out.txt) -replace '^|$', '"'
Regex ^|$ matches both the start (^) and the end ($) of the input string and replaces both with a " char., effectively enclosing the input string in double quotes.
As for what you tried:
^(.*?)
just matches the very start of the string (^), and nothing else, given that .*? - due to using the non-greedy duplication symbol ? - matches nothing else.
Therefore, replacing what matched with " only placed a " at the start of the input string, not also at the end.
You can use regex to match both:
The beginning of the line ^(.*?)
OR |
The End of the line $
I.e. ^(.*?)|$
$Flist = Get-Content "$home\$user\appfiles\out.txt"
$Flist | %{$_ -replace '^(.*?)|$', '"'}

Powershell replace last two occurrences of a '/' in file path with '.'

I have a filepath, and I'm trying to remove the last two occurrences of the / character into . and also completely remove the '{}' via Powershell to then turn that into a variable.
So, turn this:
xxx-xxx-xx\xxxxxxx\x\{xxxx-xxxxx-xxxx}\xxxxx\xxxxx
Into this:
xxx-xxx-xx\xxxxxxx\x\xxxx-xxxxx-xxxx.xxxxx.xxxxx
I've tried to get this working with the replace cmdlet, but this seems to focus more on replacing all occurrences or the first/last occurrence, which isn't my issue. Any guidance would be appreciated!
Edit:
So, I have an excel file and i'm creating a powershell script that uses a for each loop over every row, which amounts to thousands of entries. For each of those entries, I want to create a secondary variable that will take the full path, and save that path minus the last two slashes. Here's the portion of the script that i'm working on:
Foreach($script in $roboSource)
{
$logFileName = "$($script.a).txt".Replace('(?<=^[^\]+-[^\]+)-','.')
}
$script.a will output thousands of entries in this format:
xxx-xxx-xx\xxxxxxx\x{xxxx-xxxxx-xxxx}\xxxxx\xxxxx
Which is expected.
I want $logFileName to output this:
xxx-xxx-xx\xxxxxxx\x\xxxx-xxxxx-xxxx.xxxxx.xxxxx
I'm just starting to understand regex, and I believe the capture group between the parenthesis should be catching at least one of the '\', but testing attempts show no changes after adding the replace+regex.
Please let me know if I can provide more info.
Thanks!
You can do this in two fairly simply -replace operations:
Remove { and }
Replace the last two \:
$str = 'xxx-xxx-xx\xxxxxxx\x\{xxxx-xxxxx-xxxx}\xxxxx\xxxxx'
$str -replace '[{}]' -replace '\\([^\\]*)\\([^\\]*)$','.$1.$2'
The second pattern matches:
\\ # 1 literal '\'
( # open first capture group
[^\\]* # 0 or more non-'\' characters
) # close first capture group
\\ # 1 literal '\'
( # open second capture group
[^\\]* # 0 or more non-'\' characters
) # close second capture group
$ # end of string
Which we replace with the first and second capture group values, but with . before, instead of \: .$1.$2
If you're using PowerShell Core version 6.1 or newer, you can also take advantage of right-to-left -split:
($str -replace '[{}]' -split '\\',-3) -join '.'
-split '\\',-3 has the same effect as -split '\\',3, but splitting from the right rather than the left.
A 2-step approach is simplest in this case:
# Input string.
$str = 'xxx-xxx-xx\xxxxxxx\x\{xxxx-xxxxx-xxxx}\xxxxx\xxxxx'
# Get everything before the "{"
$prefix = $str -replace '\{.+'
# Get everything starting with the "{", remove "{ and "}",
# and replace "\" with "."
$suffix = $str.Substring($prefix.Length) -replace '[{}]' -replace '\\', '.'
# Output the combined result (or assign to $logFileName)
$prefix + $suffix
If you wanted to do it with a single -replace operation (with nesting), things get more complicated:
Note: This solution requires PowerShell Core (v6.1+)
$str -replace '(.+)\{(.+)\}(.+)',
{ $_.Groups[1].Value + $_.Groups[2].Value + ($_.Groups[3].Value -replace '\\', '.') }
Also see the elegant PS-Core-only -split based solution with a negative index (to split only a fixed number of tokens off the end) in Mathias R. Jessen's helpful answer.
try this
$str='xxx-xxx-xx\xxxxxxx\x\{xxxx-xxxxx-xxxx}\xxxxx\xxxxx'
#remove bracket and split for get array
$Array=$str -replace '[{}]' -split '\\'
#take all element except 2 last elements, and concat after last elems
"{0}.{1}.{2}" -f ($Array[0..($Array.Length -3)] -join '\'), $Array[-2], $Array[-1]

How to replace "\" with "\\" using powershell?

I am having a string which contains path.
$Paths = "Myfolder\Mysubfolder"
I need to replace them like "Myfolder\Mysubfolder"
But the $Paths -replace "\","\\" fails as regular expression is unable to find and replace "\".
How to replace then?
You can use .Replace() which does not use regular expressions like this:
$Paths = "Myfolder\Mysubfolder"
$Paths.replace('\','\\')
To use -replace you will need to escape the slash, since it is regex, on the match and not the substitution with the exception of $1 and $2 ...etc which are used a substitution groups.
$Paths -replace '\\','\\'
Result from both is:
Myfolder\\Mysubfolder
I'm thinking an = assignment is required?
$Paths = "Myfolder\Mysubfolder"
write-Host "debug ..... : $Paths"
$Paths = $Paths.Replace("\","\\")
write-Host "debug ..... : $Paths"
This gives:
debug ..... : Myfolder\Mysubfolder
debug ..... : Myfolder\\Mysubfolder

Powershell - print only text between quotes?

How can I have the output of the following text only show the text in the quotes (without the quotes)?
Sample text"
this is an "apple". it is red
this is an "orange". it is orange
this is an "blood orange". it is reddish
becomes:
apple
orange
blood orange
Ideally I'd like to do it in a one liner if possible. I think it's regular expression with -match but I'm not sure.
here is one way
$text='this is an "apple". it is red
this is an "orange". it is orange
this is an "blood orange". it is reddish'
$text.split("`n")|%{
$_.split('"')[1]
}
This is the winning solution
$text='this is an "apple". it is red
this is an "orange". it is orange
this is an "blood orange". it is reddish'
$text|%{$_.split('"')[1]}
Just another way using regex:
appcmd list apppool | % { [regex]::match( $_ , '(?<=")(.+)(?=")' ) } | select -expa value
or
appcmd list apppool | % { ([regex]::match( $_ , '(?<=")(.+)(?=")' )).value }
A concise solution based on .NET method [regex]::Matches(), using PSv3+ syntax:
$str = #'
this is an "apple". it is red
this is an "orange". it is orange
this is an "blood orange". it is reddish
'#
[regex]::Matches($str, '".*?"').Value -replace '"'
Regex ".*?" matches "..."-enclosed tokens and .Matches() returns all of them; .Value extracts them, and -replace '"' strips the " chars.
This means that the above even works with multiple "..." tokens per line (though note that extracting tokens with embedded escaped " chars. (e.g, \") won't work).
Use of the -match operator - which only looks for a (one) match - is an option only if:
you split the input into lines
and each line contains at most 1 "..." token (which is true for the sample input in the question).
Here'a PSv4+ solution:
# Split string into lines, then use -match to find the first "..." token
($str -split "`r?`n").ForEach({ if ($_ -match '"(.*?)"') { $Matches[1] } })
Automatic variable $Matches contains the results of the previous -match operation (if the LHS was a scalar) and index [1] contains what the 1st (and only) capture group ((...)) matched.
It would be handy if -match had a variant named, say, -matchall, so that one could write:
# WISHFUL THINKING (as of PowerShell Core 6.2)
$str -matchall '".*?"' -replace '"'
See this feature suggestion on GitHub.