Reputation: 131
While I know how I would do this in PHP, it doesn't make sense to install IIS, install PHP just to get this done.
I have a folder D:\Data
that has several subfolders in it. These folders contain files which are backups created with a program that adds a time stamp to the name to allow multiple copies of the file to be backed up.
These files need to be named:
usera.dat
But they are named currently:
usera.dat.17383947323.dat
In PHP, I would load the file name into a string, explode the string on ".", then rename the file using the [0] and [3] elements to rename the file, i.e. without the loop to read the directories:
$filename = $existing_file
$explodename = explode(".",$filename);
$newfilename = $explodename[0] . "." . $explodename[3];
rename($filename, $newfilename);
Does anyone have any recommendation on how to do this with PowerShell or a batch file looping over all the subfolders in D:\Data
?
Right now I am manually editing each file removing the extra Unix time stamp.dat part.
Upvotes: 1
Views: 109
Reputation: 174690
Translating this from PHP to PowerShell should be a breeze, let's give it a try:
$files = Get-ChildItem -Filter *.dat.*.dat
foreach($file in $files){
$filename = $file.Name
$explodename = $filename.Split('.')
$newfilename = "$($explodename[0]).$($explodename[3])"
Rename-Item $file.FullName -NewName $newfilename
}
As shown above:
explode()
function, but we can use the String.Split()
method on any string and get a string array back.
is not a string concat operator in PowerShell, but we can use subexpressions $(...)
inside an expandable string.Rename-Item
cmdlet will take care of renaming A more PowerShell-idiomatic solution would be to leverage the pipeline though:
Get-ChildItem -Filter *.dat.*.dat | Rename-Item -NewName {$explodename = $_.Name.Split('.');"$($explodename[0]).$($explodename[3])"}
You could also use a regex pattern in place of the Split()
method and string concatenation:
Get-ChildItem -Filter *.dat.*.dat | Rename-Item -NewName {$_.Name -replace '^([^\.])\..*\..*\.([^\.])$','$1.$2'}
Or do the concatenation with the -join
operator:
Get-ChildItem -Filter *.dat.*.dat | Rename-Item -NewName {$_.Name.Split('.')[0,3] -join '.'}
Whatever you fancy, Get-ChildItem
and Rename-Item
are definitely the commands you'd want to use here
Upvotes: 2
Reputation: 80113
One-liner in batch from the prompt:
@FOR /r "U:\sourcedir" %a IN (*) DO @FOR %b IN ("%~na") DO @FOR %c IN ("%~nb") DO @IF "%~xc" neq "" ECHO REN "%a" "%~nxc"
Note: echo
es the rename command for testing. Remove the echo
keyword after testing to execute the rename.
I used u:\sourcedir
as a test directory.
Translation: for each filename in the subtree (%%a
) take the name part only and assign to %%b
, repeat for %%c
and if there was no extension part in the result, then do the rename.
Upvotes: 1
Reputation: 439193
Mathias R. Jessen's answer contains many helpful pointers, but it seems that the simpler and more robust approach would be to simply drop the final 2 extensions, assuming that all files in the folder tree have these 2 extraneous extensions:
Get-ChildItem -File -Recurse D:\Data |
Rename-Item -NewName { $_.Name -replace '(\.[^.]*){2}$' }
Upvotes: 0