PowerShell Regex Bulk Replace Filenames [duplicate] - regex

This question already has answers here:
Quoting -replace & variables
(5 answers)
Closed 4 years ago.
I am trying to replace filenames in a given folder, but using regular expressions as a filter and in the new filenames, in PowerShell.
For example, a file name "CEX-13" should be renamed to "C-0013"; "CEX-14" should change to "C-0014", etc.
I have this, but I get an error that I cannot create a file that already exists.
My current code is:
foreach ($file in get-childitem | where-object {$_.name -match "^CEX-(\d\d)"})
{
rename-item $file -newname ($file.name -replace "^CEX-(\d\d)", "C-00$1")
}
Any help will be greatly appreciated.

You need the dollar in the replacement to get past the PowerShell variable expansion in strings, and stay as a dollar sign as it gets to the regex engine.
Currently "C-00$1" becomes "C-00" and all the files will get the same name.
You need to escape it with a backtick
"C-00`$1"
or use single quotes 'C-00$1'

Related

How to iterate each line of a file and print matches from a list with regex in PowerShell? [duplicate]

This question already has answers here:
Compare a string in one array, with a wildcard string in another
(3 answers)
Powershell text search - multiple matches
(2 answers)
-contains or -match several values
(2 answers)
Closed 19 days ago.
Code:
$regex = #(
'foo'
'bar'
'baz'
)
Get-Content .\foo.data | Where-Object {$_ -match $regex} | ForEach-Object {
write-host $_
}
Which was inspired by this text processing question.
The context is that I'm looking to clean up a noisy file, so lines which don't nicely fit what ConvertFrom-StringData or ConvertFrom-StringData can handle are omitted.
Only lines which match from the $regex whitelist should be output.
Looking at grep the question is seemingly: how to use and/or pattern matching in the above sample. For example:
nicholas#mordor:~/powershell$
nicholas#mordor:~/powershell$ grep -e "foo" -e "bar" foo.data
but with Powershell, and only processing a single line at a time. Effectively, running a switch to reject what's not white-listed.

How do i specify a specific file name in powershell? [duplicate]

This question already has answers here:
PowerShell String Matching and the Pipe Character
(3 answers)
Unable to escape pipe character (|) in powershell
(2 answers)
Closed 1 year ago.
I am very new to powershell. I have a csv file that i want to find and replace some text with. after some searching, this seems simple to do, but i still seem to be having problems with the code:
$csv = get-content .\test.csv
$csv = $csv -replace "|", "$"
$csv | out-file .\test.csv
My file is located here: C:\Users\CB1\test.csv
How do I specify that location in powershell?
I've tried this but it doesn't work:
$csv = get-content C:\Users\CB1\test.csv
$csv = $csv -replace "|", "$"
$csv | out-file C:\Users\CB1\test.csv
The problem isn't whether you're using relative or absolute paths (assuming your relative paths are relative to the right directory).
Rather, the problem is that the -replace operator is regex-based, and that | is therefore interpreted as a regex metacharacter (representing alternation).
Therefore, you need to escape such metacharacters, using \ (or, if you were to do this programmatically, you could use the [regex]::Escape() method).
Additionally, since your replacement operation isn't line-specific, you can speed up your operation by reading the file into memory as a whole, using the -Raw switch.
That, in turn, requires that you use the -NoNewLine switch when (re)writing the file.
Also, with text input, Set-Content is preferable to Out-File for performance reasons.
To put it all together:
(Get-Content -Raw .\test.csv) -replace '\|', '$' | Set-Content -NoNewLine .\test.csv
Note: Use the -Encoding parameter as needed, as the input file's encoding will not be honored:
In Windows PowerShell, Out-File produces UTF-16LE ("Unicode") files by default, whereas Set-Content uses the system's ANSI code page.
In PowerShell (Core) 7+, BOM-less UTF-8 is the consistently applied default.

How to preserve new line characters when performing a regex match in PowerShell [duplicate]

This question already has answers here:
Why are all newlines gone after PowerShell's Get-Content, Regex, and Set-Content?
(4 answers)
How do I match any character across multiple lines in a regular expression?
(26 answers)
Closed 2 years ago.
The goal is simple:
Take contents of text file
Search for pattern
Save search back to the file
For example, i want to find the first occurrence between # and ##. Following regex works perfectly (\#)(.*?)(?=\#{2}). It finds what I want. However, PowerShell removes all new line characters effectively changing the formatting. So, following input text
#
This
Is
My
Text
##
becomes this
# This Is My Text
How to preserve the formatting?
Here is my PowerShell script
param (
[string]$filename
)
$content = Get-Content -Path $filename
$output = $filename
$regex = [Regex]::new('(\#)(.*?)(?=\#{2})')
$matches = $regex.Matches($content)
Set-Content -Path $output $Matches[0]

Powershell Substring replacement [duplicate]

This question already has answers here:
How to handle backslash character in PowerShell -replace string operations?
(2 answers)
Closed 6 years ago.
Folks
I am unable to replace the below string in PowerShell, initially I suspected it to be due to regexp and used [regex]::Escape() to resolve the \ to double slash however it still does not work. Can you please suggest?
PS C:\User>"C:clog" -replace "C:c" , ""
PS C:\User>log
PS C:\User>"C:\\c\\log" -replace "C:\\c\\", ""
PS C:\User>C:\\c\\log
Use Split-Path, it is designed for this:
Split-Path "C:\\c\\log" -Leaf
# returns "log"

Powershell - How to UpperCase a string found with a Regex [duplicate]

This question already has answers here:
Lambda Expression in Powershell
(3 answers)
Closed 3 years ago.
I am writing a powershell script to parse the HTM file. I need to find all the links file in the file and then uppercase the filepath, filename and extention. (could be 30 or 40 links in any file). The part I'm having trouble with is the 2nd part of the -replace staement below (the 'XXXX' part). The regex WILL find the strings I'm looking for but I can't figure out how to 'replace' that string with a uppercase version, then update the existing file with a new links.
I hope I'm explaining this correctly. Appreciate any assistance that anyone can provide.
This is the code I have so far...
$FilePath = 'C:\WebDev'
$FileName = 'Class.htm'
[regex]$regex='(href="[^.]+\.htm")'
#Will Match the string href="filepath/file.htm"
( Get-Content "$FilePath\$FileName") -replace $regex , 'XXXX' | Set-Content "$FilePath\$FileName";
Final string that gets updated in the existing file should look like this HREF="FILEPATH/FILE.HTM"
Both beatcracker and briantist refer you to this answer, which shows the correct approach. Regex expressions cannot convert to uppercase, so you need to hook into the .NET String.ToUpper() function.
Instead of using -replace, use the .Replace() method on your $regex object (as described in the other answer). You also need the ForEach-Object construct so it gets called for each string in the pipeline. I've split up the last line for readability, but you can keep it on one line if you must.
$FilePath = 'C:\WebDev'
$FileName = 'Class.htm'
[regex]$regex='(href="[^.]+\.htm")'
(Get-Content "$FilePath\$FileName") |
ForEach-Object { $regex.Replace($_, {$args[0].Value.ToUpper()}) } |
Set-Content "$FilePath\$FileName"