Too many files to rename - powershell

Renaming pdf-files with the command
get-childitem | % { rename-item $_ "2017-$_"}
renames correctly 33 files but applying the same command to more than 33 files produces filenames looking like 2017-2017-2017...-original.name.
How can I surmount that limitation for which I have not found any explication?

Since Rename-Item accepts piped input there is no need for a ForEach,
to exclude files beginning with 2017- :
Get-ChildItem *.pdf -exclude 2017-*.pdf |
Rename-Item -Newname { $_.Name -replace '^','2017-' } -whatif
to exclude any year/4digit-number prefix :
Get-ChildItem *.pdf |
Where-Object Name -notmatch '^\d{4}-' |
Rename-Item -Newname { $_.Name -replace '^','2017-' } -whatif
If the output looks OK, remove the -whatif

Looks like your code is chasing it's tail (i.e. it's renaming things that have already been renamed). Capture the list of files into a variable, then loop through that, renaming the captured list of files:
$filesToRename = Get-ChildItem -Filter '*.pdf'
$filesToRename | ForEach-Object {
Rename-Item -Path $_.FullName -NewName "2017-$($_.FullName)"
}
If you want to exclude already renamed files:
$prefix = '2017-'
$filesToRename = Get-ChildItem -Filter '*.pdf' | Where-Object { !$_.Name.StartsWith($prefix) }
$filesToRename | ForEach-Object {
Rename-Item -Path $_.FullName -NewName "$prefix$($_.FullName)"
}

Related

Adding _ at the end of every file name of 3 type of extension in a folder

How could I modify name of every file by adding _ before the filename extension in a Get-ChildItem -Include without calling 3 times a Foreach.
My script works, but I would like to simplify it by using -Include and not -Filter.
function renommer_fichier {
$files = Get-ChildItem -Path C:\mestp\mesFichiers -Filter *.jpg
Foreach ($file in $files)
{
$file | Rename-Item -NewName { $_.Name -replace '.jpg', '_.jpg' }
}
$files = Get-ChildItem -Path C:\mestp\mesFichiers -Filter *.mp3
Foreach ($file in $files)
{
$file | Rename-Item -NewName { $_.Name -replace '.mp3', '_.mp3' }
}
$files = Get-ChildItem -Path C:\mestp\mesFichiers -Filter *.mpeg
Foreach ($file in $files)
{
$file | Rename-Item -NewName { $_.Name -replace '.mpeg', '_.mpeg' }
}
}
Unfortunately, the -Include parameter - which supports specifying multiple patterns - doesn't work as one would intuitively expect:
Use Get-Item instead of Get-ChildItem and append \* to the input path to make -Include work as intended.
See this answer for background information.
Use the .BaseName and .Extension properties in the delay-bind script block you're passing to Rename-Item to facilitate inserting _ before the filename extension.
Get-Item -Path C:\mestp\mesFichiers\* -Include *.jpg, *mp3, *.mpeg |
Rename-Item -WhatIf -NewName { $_.BaseName + '_' + $_.Extension }
Note: The -WhatIf common parameter in the command above previews the operation. Remove -WhatIf once you're sure the operation will do what you want.

PS to rename directory of files using only the first 4 characters

I have a directory c:\test with files 0001 test.pdf, 0002ssssit.pdf, 0003llllllllllll.pdf
My goal is to use PS to use a a loop to go through the directory and rename the files to:
0001.pdf
0002.pdf
0003.pdf
I keep getting path errors
$List = get-childitem "C:\test"
$List |Format-Wide -Column 1 -property name
ForEach($File In $List)
{
$First4 = $File.name.substring(0,4)
Rename-Item -newname $First4".pdf"
}
You need to pass the original file path to Rename-Item, otherwise it won't know what to rename!
Either:
$file | Rename-Item -NewName "${First4}.pdf"
or
Rename-Item -LiteralPath $file.FullName -NewName "${First4}.pdf"
inside the foreach body.
You could also use a single pipeline to accomplish the same (-NewName supports pipeline binding):
$List | Rename-Item -NewName { $_.Name.Substring(0,4) + $_.Extension }
try Something like this:
Get-ChildItem "c:\temp" -file "*.pdf" |
where Name -match "^[0-9]{4}" |
rename-item -NewName {"{0}{1}" -f $_.BaseName.Substring(0, 4), $_.Extension}

I want to remove recursively square brackets from file names

I have a lot of files in a directory containing square brackets for example:
Filename 1 [12454365].txt
I tried the following script but it's giving me the an error.
get-childitem -recurse | foreach { move-item -literalpath $_.name ($_.name -replace '\[.*\]', '')}
Error message
move-item : A device attached to the system is not functioning.
Only want to remove square brackets not everything in between!
If you specify -Recurse, you will need to specify the file with FullName because it will be targeted other than the current directory.
(Get-ChildItem -File -Recurse) | foreach {
$dest = Join-Path $_.DirectoryName ($_.Name -replace "[\[\]]")
Move-Item -LiteralPath $_.FullName $dest
}
Also, it is better to use Rename-Item for file renaming.
(Get-ChildItem -File -Recurse) | Rename-Item -NewName { $_.Name -replace "[\[\]]" }
I believe the issue is that you are replacing the brackets and everything in between.
Get-ChildItem * -Filter "*`[*`]*" | Rename-Item -NewName { $_.name -replace '\[','' -replace '\]','' }

UpperCase only first two letters of all filenames in a folder?

I know I can convert all filenames in a given folder to uppercase with the following:
Get-ChildItem -Path your_path -Recurse | Rename-item -NewName {$_.name.ToUpper()}
However, how can I capitalize only the first two letters of all filenames in a folder?
i.e.
ls123456_This_is_a_Test.pdf --> LS123456_This_is_a_Test.pdf
re98765_Another_Test.pdf --> RE98765_Another_Test.pdf
Thanks
Dan
Use the .SubString() method to separate the first two characters
## Q:\Test\2018\07\21\SO_51451148.ps1
$Folder = (Get-Item '.').FullName
Get-ChildItem -Path $Folder -File -Recurse |
Where-Object Name -match '^[a-z]{2}.' |
Rename-item -NewName {"{0}{1}" -f $_.Name.SubString(0,2).ToUpper(),
$_.Name.Substring(2)} -WhatIf
If the output looks OK, remove the -WhatIf parameter
try it :
Get-ChildItem "c:\temp" -file | %{
if ($_.Name.Length -gt 1)
{
$NewName="{0}{1}" -f $_.Name.SubString(0, 2).ToUpper(), $_.Name.Substring(2)
}
else
{
$NewName=$_.Name.ToUpper()
}
Rename-item $_.FullName $NewName -WhatIf
}

PowerShell script to remove characters from files and folders

I am trying to recursively remove certain characters from files and folders using a PowerShell script. Below is the script that I have found, but it will only remove underscores from files, not folders. There are a few characters which will need to be removed, but I am fine with having a script for each character if need be. It does recursively change files in the folders, but no folders are 'fixed'.
Current PowerShell script:
'dir -Recurse | where {-not $_.PsIscontainer -AND $_.name -match "_"} | foreach {
$New = $_.name.Replace("_","")
Rename-Item -path $_.Fullname -newname $New -passthru
}'
As pointed out in the comments the core of your issue is that you are excluding folders with the -Not $_.PsIscontainer component of your Where block.
dir -recurse | where {$_.name -match "_"} | ...
The second issue that you are having is most likely that since you are changing folder names the children you had previously inventoried with dir/Get-ChildItem would then have incorrect paths. One way to address this would be to process files first then folders.
$filesandfolders = Get-ChildItem -recurse | Where-Object {$_.name -match "_"}
$filesandfolders | Where-Object {!$_.PsIscontainer} | foreach {
$New=$_.name.Replace("_","")
Rename-Item -path $_.Fullname -newname $New -passthru -WhatIf
}
$filesandfolders | Where-Object {$_.PsIscontainer} | foreach {
$New=$_.name.Replace("_","")
Rename-Item -path $_.Fullname -newname $New -passthru -WhatIf
}
By no means the prettiest solution but it would work. It processes all the files first, then the folders. Remove the -Whatifs when you are sure it would do what you expect
Other characters
You had mentioned there were other characters that you were looking to remove. That wouldn't be a tall order. You could be using regex for this so lets try that.
$characters = "._"
$regex = "[$([regex]::Escape($characters))]"
$filesandfolders = Get-ChildItem -recurse | Where-Object {$_.name -match $regex}
$filesandfolders | Where-Object {!$_.PsIscontainer} | foreach {
$New=$_.name -Replace $regex
Rename-Item -path $_.Fullname -newname $New -passthru -WhatIf
}
$filesandfolders | Where-Object {$_.PsIscontainer} | foreach {
$New=$_.name -Replace $regex
Rename-Item -path $_.Fullname -newname $New -passthru -WhatIf
}
That would remove all of the periods and underscores from those files and folders.
Not tested but you might even be able to get it down to these few lines
$characters = "._"
$regex = "[$([regex]::Escape($characters))]"
$filesandfolders = Get-ChildItem -recurse | Where-Object {$_.name -match $regex}
$filesandfolders | Where-Object {!$_.PsIscontainer} | Rename-Item -NewName ($_.name -Replace $regex) -PassThru -WhatIf
$filesandfolders | Where-Object {$_.PsIscontainer} | Rename-Item -NewName ($_.name -Replace $regex) -PassThru -WhatIf