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

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
}

Related

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 '\]','' }

Too many files to rename

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)"
}

Recursively removing/renaming files using powershell

I have to go through many levels of child folders and remove special characters that are invalid in SharePoint, mainly '#&'
I have scoured the internet trying different commands; rename-item/move-item, variations of the two, all to no avail. The closest i've gotten is using:
Get-ChildItem -Recurse | Rename-Item -NewName {$_.Name -replace'[!##&]','_'}
but i keep getting this error: Rename-item: Source and destination path must be different.
Could someone point me in the right direction?
Regards
That error only happens when you attempt to rename a directory to the same NewName as the current name, you can safely ignore it.
Add -ErrorAction SilentlyContinue to silently suppress the error message:
Get-ChildItem -Recurse | Rename-Item -NewName {$_.Name -replace'[!##&]','_'} -ErrorAction SilentlyContinue
You need to filter out the files that you're not planning to rename:
Get-ChildItem -Recurse |
Where-Object { $_.Name -match '[!##&]' } |
Rename-Item -NewName {$_.Name -replace '[!##&]','_'}
something like this may work
dir -Recurse -File | ? basename -Match '[!##&]' | % {
# if the file.txt already exists, rename it to file-1.txt and so on
$num = 1
$base = $_.basename -replace'[!##&]', '_'
$ext = $_.extension
$destdir = Split-Path $_.FullName
$newname = Join-Path $destdir "$base$ext"
while (Test-Path $newname) {
$newname = Join-Path $destdir "$base-$num$ext"
$num++
}
ren $_.fullname $newname
}

how to convert function to work recursively

I have this awesome powershell script that will remove special characters from filenames:
Function Rename-Files($path)
{
Get-ChildItem -path $path |
Foreach-Object {
$newName = $_.name -replace '[^A-Za-z0-9-_ ]', ''
if (-not ($_.name -eq $newname)){
Rename-Item -Path $_.fullname -newname ($newName)
}
}
} #end function
Rename-Files -path "C:\somepath"
i would like to know whether it is possible to get this working not just on the top directory but recursively through the entire directory structure?
Just add the -Recurse Get-ChildItem parameter. e.g.
Get-ChildItem -Recurse -path $path