Retain initial characters in file names, remove all remaining characters using powershell
Retain initial characters in file names, remove all remaining characters using powershell
I have a batch of files with names like: 78887_16667_MR12_SMITH_JOHN_713_1.pdf
78887_16667_MR12_SMITH_JOHN_713_1.pdf
I need to retain the first three sets of numbers and remove everything between the third "_" and "_1.pdf".
So this: 78887_16667_MR12_SMITH_JOHN_713_1.pdf
78887_16667_MR12_SMITH_JOHN_713_1.pdf
Becomes this: 78887_16667_MR12_1.pdf
78887_16667_MR12_1.pdf
Ideally, I'd like to be able to just use the 3rd "_" as the break as the third set of numbers sometimes includes 3 characters, sometimes 4 characters (like the example) and other times, 5 characters.
If I used something like this:
Get-ChildItem Default_*.pdf | Rename-Item -NewName {$_.name -replace...
...and then I'm stuck: can I state that everything from the 3rd "" and the 6th "" should be replaced with "" (nothing)? My understanding that I'd include ".Extension" to also save the extension, too.
Look at the use of the split function: $split = $filename.split('_')
– Owain Esau
Sep 10 '18 at 22:47
Thank you @TheMadTechnician , I've edited it with what I hope is more helpful.
– Alberto_B
Sep 11 '18 at 0:10
@OwainEsau - I'm not sure what to look at exactly. :/
– Alberto_B
Sep 11 '18 at 0:10
2 Answers
2
You can use the -split
operator to split your name into _
-separated tokens, extract the tokens of interest, and then join them again with the -join
operator:
-split
_
-join
PS> ('78887_16667_MR12_SMITH_JOHN_713_1.pdf' -split '_')[0..2 + -1] -join '_'
78887_16667_MR12_1.pdf
0..2
extracts the first 3 tokens, and -1
the last one (you could write this array of indices as 0, 1, 2, -1
as well).
0..2
-1
0, 1, 2, -1
Applied in the context of renaming files:
Get-ChildItem -Filter *.pdf | Rename-Item -NewName
($_.Name -split '_')[0..2 + -1] -join '_'
-WhatIf
Common parameter -WhatIf
previews the rename operation; remove it to perform actual renaming.
-WhatIf
Glad to hear it helped, @Alberto_B; my pleasure.
– mklement0
Sep 11 '18 at 2:58
mklement0 has given you a good and working answer. Here is another way to do it using a regex.
Get-ChildItem -Filter *.pdf |
ForEach-Object
if ($_.Name -match '(.*?_.*?_.*?)_.*(_1.*)')
Rename-Item -Path $_.FullName -NewName $($Matches[1..2] -join '') -WhatIf
I think I would have done
GCI|?$_.Name -match '(^(?:.+?_)3).*_([^_]*)$'|%Rename-Item $_.FullName -NewName ($Matches[1..2] -join '')
and utilized the pipeline rather than embed an If
statement within the ForEach-Object
loop. But that's just me.– TheMadTechnician
Sep 11 '18 at 23:23
GCI|?$_.Name -match '(^(?:.+?_)3).*_([^_]*)$'|%Rename-Item $_.FullName -NewName ($Matches[1..2] -join '')
If
ForEach-Object
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Hi, welcome to StackOverflow! While I'm sure we can help, this is not a code writing service. If you could edit your question to include the code that you tried, and the trouble you are having with it I'm sure that we can get it working for you.
– TheMadTechnician
Sep 10 '18 at 22:42