I have many many files in one folder, which look like this:
- E123_1_410_4.03_97166_456_2.B.pdf
- E123-1-410-4.03-97166-456_2.B.pdf
I can change all the underscores, but not just 5 of them.
$names = "AD1-D-1234-3456-01","111-D-abcd-3456-01","abc-d-efgi-jklm-no","xxx-xx-xxxx-xxxx-xx"
$names |
ForEach-Object{
$new = $_ -replace '(?x)
^ # beginning of string
( # begin group 1
[^-]{3} # a pattern of three non-hyphen characters
) # end of group 1
- # a hyphen
( # begin group 2
[^-] # a non-hyphen (one character)
- # a hyphen
[^-]{4} # a pattern of non-hyphen characters four characters in length
- # a hyphen
[^-]{4} # a pattern of non-hyphen characters four characters in length
) # end of group 2
- # a hyphen
( # begin group 3
[^-]{2} # a pattern of non-hyphen characters two characters in length
) # end of group 3
$ # end of string
', '$1_$2_$3' # put the groups back in order and insert "_" between the three groups
if ($new -eq $_){ # check to see if the substitution worked. I.e., was the pattern in $_ correct
Write-Host "Replacement failed for '$_'"
}
else{
$new
}
}
CodePudding user response:
If you want to keep the last underscore when renaming your file, use split to deconstruct part of the word, and reconstruct the name by using a loop. At last add the dash a the end. In this way whatever the number of underscores, you can replace all of them.
Working code:
$names = "E123_1_410_4.03_97166_456-test-test_2.pdf", "E123_1_410_4.03_97166_456_2.B.pdf"
$names |
ForEach-Object{
$new = [string]::empty;
#split
$tab = $_.split("_");
#do nothing if there is only one or no dash
if($tab.count -gt 2){
#reconstruct by using keep a dash at the end
$new = $tab[0];
for($i = 1; $i -lt $tab.count - 1; $i ){
$txt = $tab[$i];
$new = "-" $txt ;
}
#add last dash
$txt = $tab[$tab.count - 1];
$new = "_" $txt;
if ($new -eq $_){ # check to see if the substitution worked. I.e., was the pattern in $_ correct
Write-Host "Replacement failed for '$_'"
}
else{
write-Host $new;
}
}
}
CodePudding user response:
This will rename the files by replacing all underscores in it to dashes, except for the last underscore:
(Get-ChildItem -Path 'X:\Where\The\Files\Are' -Filter '*_*.*' -File) | Rename-Item -NewName {
$prefix, $postfix = $_ -split '^(. )(_[^_] )$' -ne ''
"{0}$postfix" -f ($prefix -replace '_', '-')
} -WhatIf
- I have put the
Get-ChildItem
inside brackets to let it finish gathering the files first. If you leave that out, there is the possibility it might pich up files that were already renamed which is a waste of time. - The added switch
_WhatIf
is a safety device. This lets you see in the console window what the code would rename. If you are satisfied this is correct, remove the-WhatIf
switch and run the code again so the files actually are renamed.
Examples:
X:\Where\The\Files\Are\111_D_abcd_3456_01_qqq_7C.pdf --> X:\Where\The\Files\Are\111-D-abcd-3456-01-qqq_7C.pdf
X:\Where\The\Files\Are\AD1_D-1234_3456-01_xyz_3.A.pdf --> X:\Where\The\Files\Are\AD1-D-1234-3456-01-xyz_3.A.pdf
X:\Where\The\Files\Are\E123_1_410_4.03_97166_456_2.B.pdf --> X:\Where\The\Files\Are\E123-1-410-4.03-97166-456_2.B.pdf