问题
I have a bunch of csv files I would like to rename with powershell.
from
abc-def-ghi-jkl-mno-pqr-ke-traffic-by-domains-17-Oct-2018_23-49-38-6d73395f476ad09a7506dc00533933b8.csv
abc-def-ghi-jkl-mno-pqr-ke-traffic-by-domains-15-Oct-2018_05-20-36-75eabae7c4123198ff5fe6f4f642449f.csv
abc-def-ghi-jkl-mno-pqr-ke-traffic-by-domains-12-Oct-2018_06-23-58-b13eb8f362c09fbe405458fac8af8f8e.csv
to
abc-17-Oct-2018.csv
abc-15-Oct-2018.csv
abc-12-Oct-2018.csv
I could delete the characters after the underscore (_) with this command
Get-ChildItem -Filter *.csv | Foreach-Object -Process {
$NewName = [Regex]::Match($_.Name,"^[^_]*").Value + '.csv'
$_ | Rename-Item -NewName $NewName}
which leads me to this file name
abc-def-ghi-jkl-mno-pqr-ke-traffic-by-domains-17-Oct-2018.csv
but I am lost at deleting the range of characters from the first hyphen to the third from last hyphen.
I tried this but get an error.
Get-ChildItem -Filter *.csv | Rename-Item -NewName {
-replace '^[^-]..^[^-]{-3}','^[^-]'}
Could somebody kindly enlighten me how to erase a range? (and possibly combine the former command)
回答1:
Assuming that all input filenames have the same number of tokens with the same separators in the same positions:
Get-ChildItem -Filter *.csv | Rename-Item -NewName {
(($_.Name -split '[-_]')[0, 10, 11, 12] -join '-') + '.csv'
} -WhatIf
-WhatIf
previews the renaming operations; remove it to perform actual renaming.
Splitting the filename into tokens by separators avoids complex regexes; PowerShell's flexible array slicing makes it easy to piece together the target filename from the tokens of interest accessed by their indices.
That said, if you wanted to do it with -replace
and a complex regex:
Get-ChildItem -Filter *.csv | Rename-Item -NewName {
$_.Name -replace '^([^-]+).*?-(\d[^_]+).*', '$1-$2.csv'
} -Whatif
This solution doesn't assume a fixed position of the 2nd token to extract - the one before _
- and instead identifies its start by a -
followed by a digit (\d
).
回答2:
So I found a very long and convoluted way to do it, but it works so it works.
# Adds files into an object
$CSV = Get-ChildItem "C:\temp\test\*.csv"
# Create a loop to action each file in the object created above
Foreach($File in $CSV){
# Splits each part of the filename using the hyphen
$NewName = @($File.basename.Split('-'))
# created a new name using each individual part of the split original name
# Also replaced the underscore section
$NewFileName = "$($NewName[0])"+"-"+"$($NewName[10])"+"-"+"$($NewName[11])"+"-"+"$($NewName[12] -replace '_.*')"+".csv"
# Renames file
Rename-Item $File $NewFileName
}
回答3:
How about extract only what you need for the rename. Meaning What I tested. RegEx to trap first 4, date, and last 4. How I tested this approach.
Clear-Host
Write-Host "`nCreate the the file set *********" -ForegroundColor Cyan
'abc-def-ghi-jkl-mno-pqr-ke-traffic-by-domains-17-Oct-2018_23-49-38-6d73395f476ad09a7506dc00533933b8.csv',
'abc-def-ghi-jkl-mno-pqr-ke-traffic-by-domains-15-Oct-2018_05-20-36-75eabae7c4123198ff5fe6f4f642449f.csv',
'abc-def-ghi-jkl-mno-pqr-ke-traffic-by-domains-12-Oct-2018_06-23-58-b13eb8f362c09fbe405458fac8af8f8e.csv' |
%{New-Item -Path 'D:\Temp' -Name $_ -ItemType File}
Write-Host "`nValidate the file set creation *********" -ForegroundColor Cyan
(Get-ChildItem -Path 'D:\Temp' -Filter 'abc*').FullName
Write-Host "`nRead the folder for the file set and rename based on regex to shorten the name *********" -ForegroundColor Cyan
Get-ChildItem -Path 'D:\Temp' -Filter 'abc*' |
%{ Rename-Item -Path $_.FullName -NewName ([regex]::Matches($_.Name,'^.{0,4}|\d{2}.*\-\d{4}|.{4}$').Value -join '')}
Write-Host "`nValidate the name change *********" -ForegroundColor Cyan
(Get-ChildItem -Path 'D:\Temp' -Filter 'abc*').FullName
# Results
Create the the file set *********
Directory: D:\Temp
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 10/18/2018 9:29 PM 0 abc-def-ghi-jkl-mno-pqr-ke-traffic-by-domains-17-Oct-2018_23-49-38-6d73395f476ad09a7506dc00533933b8.csv
-a---- 10/18/2018 9:29 PM 0 abc-def-ghi-jkl-mno-pqr-ke-traffic-by-domains-15-Oct-2018_05-20-36-75eabae7c4123198ff5fe6f4f642449f.csv
-a---- 10/18/2018 9:29 PM 0 abc-def-ghi-jkl-mno-pqr-ke-traffic-by-domains-12-Oct-2018_06-23-58-b13eb8f362c09fbe405458fac8af8f8e.csv
Validate the file set creation *********
D:\Temp\abc-def-ghi-jkl-mno-pqr-ke-traffic-by-domains-12-Oct-2018_06-23-58-b13eb8f362c09fbe405458fac8af8f8e.csv
D:\Temp\abc-def-ghi-jkl-mno-pqr-ke-traffic-by-domains-15-Oct-2018_05-20-36-75eabae7c4123198ff5fe6f4f642449f.csv
D:\Temp\abc-def-ghi-jkl-mno-pqr-ke-traffic-by-domains-17-Oct-2018_23-49-38-6d73395f476ad09a7506dc00533933b8.csv
Read the folder for the file set and rename based on regex to shorten the name *********
Validate the name change *********
D:\Temp\abc-12-Oct-2018.csv
D:\Temp\abc-15-Oct-2018.csv
D:\Temp\abc-17-Oct-2018.csv
来源:https://stackoverflow.com/questions/52884866/renaming-a-range-from-files-w-powershell-from-first-to-third-from-last-hyphen