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-ChildIteminside 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
_WhatIfis 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-WhatIfswitch 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
