Reputation: 1654
Hello I would like to know is there a way to replace multiple filenames from parent folder?
I was able to rename multiple files using command below, but I have to access each folder first to rename multiple files.
dir .\* -include ('*.mp4','*.srt') | Rename-Item -NewName { $_.Name -replace '\[','' -replace '\]','' }
I was trying to replace dir .\*
to dir .\**\*
to select from parent folder but didn't work.
What am I missing?
Upvotes: 2
Views: 1113
Reputation: 1654
I just found out I could use dir .
to select all files (with specific file types), including files in subdirectories.
dir . -Recurse -Include ('*.srt', '*.mp4') | Rename-Item -NewName { $_.Name -replace '\[|\]','' }
Upvotes: 1
Reputation: 61263
You can do that by adding the -Recurse
switch to Get-ChildItem
(dir is alias to Get-ChildItem).
When searching for files that contain square brackets, you need to use the -LiteralPath
parameter.
Also, be aware that there is a snag if you pipe the results from that directly to Rename-Item
..
When doing so, Get-ChildItem
may pick up the already processed files again, wasting time of course, so to prevent that you can either do:
$rootFolder = 'X:\WhereTheFilesAre'
(Get-ChildItem -LiteralPath $rootFolder -Include '*.mp4','*.srt' -File -Recurse) |
Rename-Item -NewName { $_.Name -replace '\[|]' }
or
$rootFolder = 'X:\WhereTheFilesAre'
$files = Get-ChildItem -LiteralPath $rootFolder -Include '*.mp4','*.srt' -File -Recurse
foreach ($file in $files) {
$file | Rename-Item -NewName { $file.Name -replace '\[|]' }
}
Upvotes: 5
Reputation: 7087
In additional to marsze's concise answer and realizing this isn't really a performance question:
-Include
is much slower than -Filter
because it filters after retrieving from the file system. Whereas, -Filter
has the file system do the heavy lifting. In essence -Filter
is a nuanced version of moving filtering operations left in the command/pipeline to improve performance. However, -Filter
doesn't take multiple values! That said, you may still be able to exploit this characteristic using a loop, something like:
'*.mp4','*.srt' |
ForEach-Object{
Get-ChildItem .\ -Filter $_ -File
} |
Rename-Item -NewName { $_.Name -replace '\[|\]' }
-File
works even though you are using -Recurse
and may carry a modest performance improvement. I also shortened the -replace
to 1 operation which can only help further.
Upvotes: 4
Reputation: 17164
What you probably want is the -Recurse
switch:
dir "the folder" -Recurse -Include ('*.mp4','*.srt')
Note that this will recurse all levels of subdirectories.
Upvotes: 3