how to change file names to their default with powershell - powershell

I just wanted to re-number my music files based on their date creation on windows 10 and I found this PowerShell script on the internet.
[ref]$i = 1; gci -file | Rename-Item -NewName {'{0:D} - {1}' -f $i.Value++, $_}
but this code didn't do that.
After that, I used the below code but unfortunately, my file names were broken and converted to numbers! see the code and image below
$count = 1; Get-ChildItem -File | Sort-Object LastWriteTime | Rename-Item -NewName { '{0:D {1}' -f $script:count++, $_.Extension }
So now I want to first rename my files to their default name and after that, I would like to re-number them by their date of creation. For example, if assuming my latest song is "song1.mp3" it should turn to "1 - song1.mp3".
Tnx a lot.

Related

Batch renaming files by PowerShell?

How can I rename files in a folder that have random names and random extensions to a sequence like the example below: 0001.pdf 0002.pdf ..... 0100.png and continue.
And if possible then generate a .txt file with the names and extensions generated.
For the .txt file if not possible Powershel could be another application.
Searching I got the code below, but I can't fix it for the task I need.
Dir | Rename-Item –NewName { $_.name –replace " - ","0" }
Wrap the call to Rename-Item in ForEach-Object then maintain a counter in a variable:
$fileNumber = 1
Get-ChildItem path\to\folder\containing\random\files -File |ForEach-Object {
# Construct new file name
$newName = '{0:0000}{1}' -f $fileNumber,$_.Extension
# Perform rename
$_ |Rename-Item -NewName $newName
# Increment number
$fileNumber++
}

Bulk renaming files with different extensions in order using powershell

is there a way to bulk rename items such that a folder with the items arranged in order would have their name changed into numbers with zero padding regardless of extension?
for example, a folder with files named:
file1.jpg
file2.jpg
file3.jpg
file4.png
file5.png
file6.png
file7.png
file8.jpg
file9.jpg
file10.mp4
would end up like this:
01.jpg
02.jpg
03.jpg
04.png
05.png
06.png
07.png
08.jpg
09.jpg
10.mp4
i had a script i found somewhere that can rename files in alphabetical order. however, it seems to only accepts conventionally bulk renamed files (done by selecting all the files, and renaming them such that they read "file (1).jpg" etc), which messes up the ordering when dealing with differing file extensions. it also doesn't seem to rename files with variations in their file names. here is what the code looked like:
Get-ChildItem -Path C:\Directory -Filter file* | % {
$matched = $_.BaseName -match "\((?<number>\d+)\)"
if (-not $matched) {break;}
[int]$number = $Matches["number"]
Rename-Item -Path $_.FullName -NewName "$($number.ToString("000"))$($_.Extension)"
}
If your intent is to rename the files based on the ending digits of their BaseName you can use Get-ChildItem in combination with Where-Object for filtering them and then pipe this result to Rename-Item using a delay-bind script block.
Needles to say, this code does not handle file collision. If there is more than one file with the same ending digits and the same extension this will error out.
Get-ChildItem -Filter file* | Where-Object { $_.BaseName -match '\d+$' } |
Rename-Item -NewName {
$basename = '{0:00}' -f [int][regex]::Match($_.BaseName, '\d+$').Value
$basename + $_.Extension
}
To test the code you can use the following:
#'
file1.jpg
file2.jpg
file3.jpg
file4.png
file5.png
file6.png
file7.png
file8.jpg
file9.jpg
file10.mp4
'# -split '\r?\n' -as [System.IO.FileInfo[]] | ForEach-Object {
$basename = '{0:00}' -f [int][regex]::Match($_.BaseName, '\d+$').Value
$basename + $_.Extension
}
You could just use the number of files found in the folder to create the appropriate 'numbering' format for renaming them.
$files = (Get-ChildItem -Path 'D:\Test' -File) | Sort-Object Name
# depending on the number of files, create a formating template
# to get the number of leading zeros correct.
# example: 645 files would create this format: '{0:000}{1}'
$format = '{0:' + '0' * ($files.Count).ToString().Length + '}{1}'
# a counter for the index number
$index = 1
# now loop over the files and rename them
foreach ($file in $files) {
$file | Rename-Item -NewName ($format -f $index++, $file.Extension) -WhatIf
}
The -WhatIf switch is a safety measure. With this, no file gets actually renamed, you will only see in the console what WOULD happen. Once you are content with that, remove the -WhatIf switch from the code and run again to rename all your files in the folder

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

Need to change lastwritetime in renaming file

I would like to ask help for the lastwritetime need to change if its multiple files having the same time stamp.
I am using below query to fetch and rename the file name with my predefined $prefix+$lastwritetime, suppose if multiple files having same timestamp means I am unable to rename the files, hence the first file is rename with Lastwritetime in that situation I need to change my Lastwritetimes seconds so that files will be created.
Thanks for your kind help.
$FilePath = $ToPath+"\"+$ToFile
Get-ChildItem -Path $FilePath | Foreach { Rename-Item $_ -NewName ($Prefix+$_.LastWriteTime.ToString("yyMMddhhmm")) }
suppose Lastwritetime is 20190619082733 for two files i need it as 20190619082734 + or - is fine. I have tried with AddMinutes(-"2") but something i am missing kindly advise.
Try addminutes(-2). It takes an int and not a string. Something like:
Get-ChildItem -Path $FilePath | Foreach-Object {
$DateString = $_.LastWriteTime.AddMinutes(-2).ToString("yyMMddhhmm")
Rename-Item $_.FullName -NewName ($Prefix + $DateString + $_.Extension)
}
If you want your string to include seconds, you should format it like this:
$DateString = $_.LastWriteTime.AddMinutes(-2).ToString("yyMMddhhmmss")

Removing part of a file name before copy using PowerShell

I need to rename files during the copy process and strip out part of the file name. What I have been doing before users added to the file name was simple:
dir $PROCDIR\$PDFTYPE\holding_pattern\*.pdf -recurse | sort -property lastwritetime | select -first 1 | move-item -destination $PROCDIR\$PDFTYPE\begin_processing
The file name format that I am working with is now xxx_xxx_xxx_xxx_xxx.pdf where the _ splits the information apart. The x's are just an example because the file could be named LakeTahoe_February15_Airplane_0115201457_baseball.pdf. When I perform the copy I need to keep the first three.... so from aaa_aaa_aaa_aaa_aaa.pdf to aaa_aaa_aaa.pdf. Basically stripping out the last two. Further if there is nothing beyond LakeTahoe_February15_Airplane_.pdf I want to get rid of the last "_" as well.
I am still very new with powershell but learning. It is good stuff however frustrates me from time to time :). Ideas?
Thanks!
Here is a regex solution that might help you out:
dir $PROCDIR\$PDFTYPE\holding_pattern\*.pdf | sort -property lastwritetime | select -first 1 | % { $_.Name -match '.*?_.*?_.*?(?=_)'; $Target = '$PROCDIR\$PDFTYPE\begin_processing\{0}.pdf' -f $matches[0]; Move-Item -Path $_.FullName -Destination $Target -WhatIf; };
The results I got during my test seem to indicate that the move/rename operation was successful:
What if: Performing the operation "Move File" on target "Item: C:\test\asdf_blah_asdf_qwer_trew_ytui - Copy.pdf Destination: C:\Windows\System32\WindowsPowerShell\v1.0\$PROCDIR\$PDFTYPE\begin_processing\asdf_blah_a
sdf.pdf".
You can safely ignore the phony destination path in my example, since I don't have the $ProcDir and $PDFType variables defined.
Here's a version that's a bit more readable, on multiple lines.
Get-ChildItem -Path c:\test\*.pdf |
Sort-Object -Property lastwritetime | Select-Object -First 1 |
ForEach-Object -Process { $_.Name -match '.*?_.*?_.*?(?=_)'; $Target = 'c:\test\subtest\{0}.pdf' -f $matches[0]; Move-Item -Path $_.FullName -Destination $Target -WhatIf; };
Result:
What if: Performing the operation "Move File" on target "Item: C:\test\asdf_blah_asdf_qwer_trew_ytui - Copy.pdf Destination: C:\test\subtest\asdf_blah_asdf.pdf".
Another way to do it, inline and more succinct (this is the last stage of your pipleine; everything that precedes it stays the same):
| mi -Des $PROCDIR\$PDFTYPE\begin_processing\$(($_.Name -split '_')[0..2] -join '_').pdf
(mi -Des is the same as Move-Item -Destination; I used the short version to fit it into one line without scroll bars.)
What this does is splits the base filename into an array of the underscore-separated parts, selects the first three elements of the array (i.e., the first three parts of the filename), glues them back together with underscores, and tacks the .pdf extension back on.
Another approach is to use the -replace operator to match the part you want to get rid of and replace it with an empty string:
| mi -Des $PROCDIR\$PDFTYPE\begin_processing\$($_.Name -replace '(_[^_]+){2}(?=\.)', '')