Rename multiple folders containing special characters - powershell

I'm trying to process a folder of a few hundred folders that all have parenthesis and square brackets in the name, but also have an unwanted space before the square bracket that I would like removed.
example: c:/Documents/MainFolder/Subfolder1Title (Attribute1) (Attribute2) [UniqueNumber ] - []
(Where the space after "UniqueNumber is the unwanted space"
I would like to write a script that looks for all folders that have " ] - []" and replace it with "] - []" without changing the rest of the folder name, so that it ends up as: c:/Documents/MainFolder/Subfolder1Title (Attribute1) (Attribute2) [UniqueNumber] - []
I've tried several solutions from other questions, but most deal with just files instead of folders, and for some reason there's an issue with the square brackets that just seemingly can't be resolved. ( with use of `` before the [ )
Example:
$dir = "c:/Documents/MainFolder/"
CD $dir
Get-ChildItem | `
Where-Object {$_.Name -match ' ] - []'} | `
Rename-Item -LiteralPath $_fullname -NewName $_.fullname.replace ( " ] - []" , "] - []")
Please help.

Avoid asking multiple distinct questions at once. I will just answer the first question which is related to your question title.
The -match takes a regex, therefore you have to escape the [.
$_fullname is missing a dot.
Since you are using powershell-v2, you probably have to use curly brackets.
This should work:
Get-ChildItem | Where-Object {$_.Name -match '\s+]\s+-\s+\[]'} |
Rename-Item -NewName ({$_.fullname -replace "\s+]\s+-\s+\[]" , "] - []"})
Note: You should not change the directory, instead specify the path within the Get-ChildItem cmdlet.
Here the script I used that works:
$dir = "c:/" # changed this to C:/
# Create a Sample folder
$sampleFolderPath = Join-Path $dir 'Subfolder1Title (Attribute1) (Attribute2) [UniqueNumber ] - []'
New-Item $sampleFolderPath -ItemType Directory -Force
# Now lets rename it
Get-ChildItem -Path $dir |
Where-Object {$_.Name -match '\s+]\s+-\s+\[]'} |
Rename-Item -NewName ({$_.fullname -replace "\s+]\s+-\s+\[]" , "] - []"})

Related

Inserting space before every capitalized characters for word documents name using power shell

I am working on inserting the space before every capitalized characters to rename the word documents in power shell
I tried to insert the space before first character for every file in this folder using the following script in power shell:
Could you pls let me know how to write a script to insert and iterate ?
#Target: the files names will appear as shown here: 220519ColdWaterMeters[enter image description here][1] , change all of the file names by adding a spaces in the file names so it will read as “220519 Cold Water Meters”
previous code
PS C:\Users\B> $source_path = "C:\Temp"
PS C:\Users\B> $filter = "*.doc"
PS C:\Users\B> $new_prefix = " "
PS C:\Users\B> $files = Get-ChildItem -Path $source_path -Filter $filter
PS C:\Users\B> # Process each file and add the $new_prefix to the filenames
>> ForEach ($file in $files) {
>>
>> $old_file_name = $file.Name
>> $new_full_name = "$($file.DirectoryName)" + "\" + "$($new_prefix)" + "$($old_file_name)"
>>
>> # Rename the file (perhaps first with the -WhatIf parameter?)
>> # Rename-Item $file.FullName -NewName $new_full_name -WhatIf
>> Rename-Item $file.FullName -NewName $new_full_name
>>
>> } # ForEach $file
Really, having spaces in filenames, folder names, filed names, property names, is a prescription for unneeded headaches in coding later. Doing so, can/will cause quoting complexities.
Yet, if you really want to do this, try this approach.
'220519ColdWaterMeters' -csplit '(?=[A-Z])' -ne '' -join ' '
# Results
<#
220519 Cold Water Meters
#>
You can use -creplace with delay-bind scriptblock in one pipeline like this.
$source_path = "C:\Temp"
$filter = "*.doc"
$new_prefix = " "
Get-ChildItem -Path $source_path -Filter $filter |
Rename-Item -NewName {($_.basename -creplace '(?=[A-Z])',"$new_prefix") + $_.Extension}
Just in case the extension had a capital letter I targeted just the basename and then added the extension back.

PowerShell - Why is this not renaming my files?

I have been looking around for a way to quickly and easily rename hundreds os files in one go.
something where I only have to change smalle parts for it to be reused somewhere else.
So i ended up starting to make this script. shown below...
the output should come out like this:
Show Title - SXX.EXXX - Episode title - [release year]
the raw files all looks like this:
XXX Episode title [release year]
It does not work right now. and i haven't been able to see why yet.
Whenever i run it, it does nothing. but i do not get any error message.
$ShowTitle = "My Title -"
$SeasonNumber = "02"
# Getting all child files (In ALL subfolders)
$files = Get-Childitem –Path Get-Location -Recurse |
Where-Object { $_.Name -match $_.Name } |
# Insert a ' - ' between the episode number and the episode text.
Rename-Item -NewName {$_.BaseName.insert(5,'-') + $_.Extension} |
# Append title and season number to the beginning of the file.
Rename-Item -NewName { $ShowTitle + "S" + $SeasonNumber + ".E" + $_.Name} |
# Makes a "-" between episode title and year of release.
Rename-Item -NewName { $_.Name -replace '\[', '- [' }
it worked on a smaller scale before. like this:
$files = Get-Childitem –Path "C:\Users\user\Videos\Series\show\Season x" -Recurse |
Where-Object { $_.Name -match 'show title' } |
Rename-Item -NewName { $_.Name -replace '\[', '- [' }
But i would like to do all the steps above in one go.
Can someone give me a hint so I can find the right answer to my little problem?
Thank you in advance.
You've got a lot of bugs here.
Get-Childitem –Path Get-Location -Recurse
This doesn't make sense. You're looking for a file or folder in the current directory with the literal name Get-Location. Like C:\Get-Location\. If you want to get the files in the current directory, you just don't specify the -Path parameter: Get-ChildItem -Recurse.
Where-Object { $_.Name -match $_.Name } is kind of nonsense code? The right hand side of the -match operator is going to be treated as a regular expression. That means . means "any character", square brackets and parentheses have special meaning, and so on. It's often going to always be true, but I can't imagine that you actually want to do what that says. It's very possible to construct a valid filename that doesn't match a regular expression with the same string value. For example '[01] File.avi' -match '[01] File.avi' is false.
Second, the -NewName parameter takes a string, while {$_.BaseName.insert(5,'-') + $_.Extension} is a ScriptBlock. That may work because some parts of Powershell allow that, but idiomatically I would say that it's wrong because it will not work consistently. A better option would be to use a string with embedded subexpressions like -NewName "$($_.BaseName.Insert(5,'-'))$($_.Extension)"
Finally, Rename-Item doesn't pass any output to the pipeline without the -PassThru parameter. You'd only process the first item and then I imagine the system would complain of an empty pipeline or only the first Rename-Item would do anything.
Try something like this:
$ShowTitle = "My Title -"
$SeasonNumber = "02"
# Getting all child files (In ALL subfolders)
$files = Get-Childitem -Recurse |
Where-Object { $_.Name -match 'some value or delete this command if you want all files' } |
# Insert a ' - ' between the episode number and the episode text.
Rename-Item -NewName "$($_.BaseName.Insert(5,'-'))$($_.Extension)" -PassThru |
# Append title and season number to the beginning of the file.
Rename-Item -NewName "$($ShowTitle)S$($SeasonNumber).E$($_.Name)" -PassThru |
# Makes a "-" between episode title and year of release.
Rename-Item -NewName "$($_.Name -replace '\[', '- [')" -PassThru

Powershell add suffix to filenames, based on prefix

I have a directory that consists of a number of text files that have been named:
1Customer.txt
2Customer.txt
...
99Customer.txt
I am trying to create powershell script that will rename the files to a more logical:
Customer1.txt
Customer2.txt
...
Customer99.txt
The prefix can be anything from 1 digit to 3 digits.
As I am new to powershell, I really don't know how I can achieve this. Any help much appreciated.
The most straigth forward way is a gci/ls/dir
with a where matching only BaseNames starting with a number with a
RegEx and piping to
Rename-Item and building the new name from submatches.
ls |? BaseName -match '^(\d+)([^0-9].*)$' |ren -new {"{0}{1}{2}" -f $matches[2],$matches[1],$_.extension}
The same code without aliases
Get-ChildItem |Where-Obect {$_.BaseName -match '^(\d+)([^0-9].*)$'} |
Rename-Item -NewName {"{0}{1}{2}" -f $matches[2],$matches[1],$_.extension}
Here is one way to do it:
Get-ChildItem .\Docs -File |
ForEach-Object {
if($_.Name -match "^(?<Number>\d+)(?<Type>\w+)\.\w+$")
{
Rename-Item -Path $_.FullName -NewName "$($matches.Type)$($matches.Number)$($_.Extension)"
}
}
The line:
$_.Name -match "^(?<Number>\d+)(?<Type>\w+)\.\w+$")
takes the file name (e.g. '23Suppliers.txt') and perform a pattern match on it, pulling out the number part (23) and the 'type' part ('Suppliers'), naming them 'Number' and 'Type' respectively. These are stored by PowerShell in its automatic variable $matches, which is used when working with regular expressions.
We then reconstruct the new file using details from the original file, such as the file's extension ($_.Extension) and the matched type ($matches.Type) and number ($matches.Number):
"$($matches.Type)$($matches.Number)$($_.Extension)"
I'm sure there's a nicer way to do this with regex, but the following is a quick first go at it:
$prefix = "Customer"
Get-ChildItem C:\folder\*$prefix.txt | Rename-Item -NewName {$prefix + ($_.Name -replace $prefix,'')}

Powershell renaming a specific Character

I've been batch renaming .las files in powershell with a simple script:
cd "C:\Users\User\desktop\Folder"
Dir | Rename-Item -NewName {$_.name-replace "-", "" }
Dir | Rename-Item -NewName {$_.name-replace "_", "" }
Dir | Rename-Item -NewName {$_.BaseName+ "0.las"}
This has been working great, but I need to modify it to account for a different naming convention.
The files start out in this format: 123_45-67-890-12W_0
and get converted to 123456789012W00.las
Occasionally the number after the W will be non zero, and I need to carry that on as the last digit, eg. 123_45-67-890-12W_2 needs to go to 123456789012W02
I'm not sure how to use if statements and to select a specific digit in powershell format, which is how I would approach this problem. Does anyone have some ideas on how to go about this?
Thanks
You can use a regular expression to achieve this:
Get-ChildItem "C:\Users\User\desktop\Folder" | ForEach-Object {
#capture everything we need with regex
$newName = $_.Name -replace "(\d{3})_(\d{2})-(\d{2})-(\d{3})-(\d{2})(\w)_(\d)",'$1$2$3$4$5$6$7'
#insert 0 before last digit and append file extension
$newName = $newName.Insert(($newName.Length - 1), "0") + ".las"
#rename file
Rename-Item $_.FullName -NewName $newName
}
You can use the substring method to get all but the last character in the basename, then concatenate the zero, then use substring again to get the basename's last character, then finish off with the .las extension:
Dir | Rename-Item -NewName {($_.BaseName).substring(0,$_.BaseName.length - 1) + "0" + ($_.BaseName).substring($_.BaseName.length -1,1) + ".las"}
# ^^^^This gets everything but the last charcter^^^ ^^^^^^^^^^This gets the last character^^^^^^^^^^

How to remove some words from all text file in a folder by powershell?

I have a situation that I need to remove some words from all text file in a folder.
I know how to do that only in 1 file, but I need to do it automatically for all text files in that folder. I got no idea at all how to do it in powershell.
The name of the files are random.
Please help.
This is the code
$txt = get-content c:\work\test\01.i
$txt[0] = $txt[0] -replace '-'
$txt[$txt.length - 1 ] = $txt[$txt.length - 1 ] -replace '-'
$txt | set-content c:\work\test\01.i
Basicly it jsut removes a "-" from first line and last line, but i need to do this on all files in the folder.
Get-ChildItem c:\yourfolder -Filter *.txt | Foreach-Object{
... your code goes here ...
... you can access the current file name via $_.FullName ...
}
Here is a full working example:
Get-ChildItem c:\yourdirectory -Filter *.txt | Foreach-Object{
(Get-Content $_.FullName) |
Foreach-Object {$_ -replace "what you want to replace", "what to replace it with"} |
Set-Content $_.FullName
}
Now for a quick explanation:
Get-ChildItem with a Filter: gets all items ending in .txt
1st ForEach-Object: will perform the commands within the curly brackets
Get-Content $_.FullName: grabs the name of the .txt file
2nd ForEach-Object: will perform the replacement of text within the file
Set-Content $_.FullName: replaces the original file with the new file containing the changes
Important Note: -replace is working with a regular expression so if your string of text has any special characters
something like this ?
ls c:\temp\*.txt | %{ $newcontent=(gc $_) -replace "test","toto" |sc $_ }
$files = get-item c:\temp\*.txt
foreach ($file in $files){(Get-Content $file) | ForEach-Object {$_ -replace 'ur word','new word'} | Out-File $file}
I hope this helps.
Use Get-Childitem to filter for the files you want to modify. Per response to previous question "Powershell, like Windows, uses the extension of the file to determine the filetype."
Also:
You will replace ALL "-" with "" on the first and last lines, using what your example shows, IF you use this instead:
$txt[0] = $txt[0] -replace '-', ''
$txt[$txt.length - 1 ] = $txt[$txt.length - 1 ] -replace '-', ''