powershell - 如何从文件名中删除最后 X 个字符
问题描述
寻求帮助编写一个脚本,该脚本将从文件名的末尾删除特定数量的字符。在我的具体困境中,我有几十个格式如下的文件:
1234567 XKJDFDA.pdf
5413874 KJDFSXZ.pdf
……等等等等。
我需要删除最后 7 个字母字符以保留 7 位数字作为文件名。通过另一个发布的问题,我能够找到一个脚本,该脚本将删除文件名开头的前X个数字,但我很难修改它以从末尾删除:
get-childitem *.pdf | rename-item -newname { [string]($_.name).substring(x) }
任何和所有相关的帮助将不胜感激。
尊敬,
解决方案
$RootFolder = '\\server.domain.local\share\folder'
Get-ChildItem -LiteralPath $RootFolder -Filter '*.pdf' |
Where-Object { $_.psIsContainer -eq $false } | # No folders
ForEach-Object {
if ($_.Name -match '^(?<BeginningDigits>\d{7})\s.+\.pdf$' ) {
$local:newName = "$($Matches['BeginningDigits'])$($_.Extension)"
return Rename-Item -LiteralPath $_.FullName -NewName $local:newName -PassThru
}
} |
ForEach-Object {Write-Host "New name: $($_.Name)"}
如果文件名与“ <FilenameBegin><SevenDigits><Space><Something>.pdf<FilenameEnd>
”匹配,则将其重命名为“ <SevenDigits>.<KeepExtension>
”。这使用带有命名选择组的正则表达式(<BeginningDigits>
是组名)。请注意,由于 RegExp 的使用,这是最占用 CPU 的算法,但如果您有一次性运行或文件量很少,则没有任何意义。否则,如果您有很多文件,我建议在 RegExp 检查之前添加Where-Object { $_.BaseName.Length -gt 7 } |
beforeif (.. -match ..)
以过滤掉短于 7 个符号的文件,以最大限度地减少 CPU 使用率(字符串长度检查比 RegExp 消耗的 CPU 更少)。您也可以\.pdf
从 RegExp 中删除以最小化 CPU 使用率,因为您已经拥有此过滤器Get-ChildItem
如果您严格需要匹配“ <7digits><space><7alpha>.pdf
”,则应将 RegExp 表达式替换为'^(?<BeginningDigits>\d{7})\s[A-Z]{7}\.pdf$'
$RootFolder = '\\server.domain.local\share\folder'
@( Get-ChildItem -LiteralPath $RootFolder -Filter '*.pdf' ) |
Where-Object { $_.psIsContainer -eq $false } | # No folders
Where-Object { $_.BaseName.Length -gt 7 } | # For files where basename (name without extension) have more than 7 symbols)
ForEach-Object {
$local:newName = [string]::Join('', $_.BaseName.ToCharArray()[0..6] )
return Rename-Item -LiteralPath $_.FullName -NewName $local:newName -PassThru
} |
ForEach-Object {Write-Host "New name: $($_.Name)"}
替代方案:使用字符串拆分连接:重命名所有文件,其名称不带扩展名 > 7 个符号为前 7 个符号(不考虑是否为数字),保留扩展名。这是愚蠢的算法,因为 Substring 更快。这只是可以帮助学习使用子阵列选择[x..y]
请注意,我们在使用[x..y]
in之前检查字符串长度 > 7 Where-Object { $_.BaseName.Length -gt 7 }
。否则,当名称短于 7 个符号并且我们尝试采用第 7 个符号时,我们会遇到错误。
$RootFolder = '\\server.domain.local\share\folder'
@( Get-ChildItem -LiteralPath $RootFolder -Filter '*.pdf' ) |
Where-Object { $_.psIsContainer -eq $false }
Where-Object { $_.BaseName.Length -gt 7 } | # For files where basename (name without extension) have more than 7 symbols)
ForEach-Object {
$local:newName = $x[0].BaseName.Substring(0,7)
return Rename-Item -LiteralPath $_.FullName -NewName $local:newName -PassThru
} |
ForEach-Object {Write-Host "New name: $($_.Name)"}
替代方案:使用子字符串。将所有不带扩展名> 7个符号的文件重命名为前7个符号(不考虑是否为数字),保留扩展名。
.Substring(0,7)
# 0 - 第一个符号的位置,7 - 需要多少个符号。请注意,我们在使用 substring in 之前检查字符串长度 > 7 Where-Object { $_.BaseName.Length -gt 7 }
。否则,当名称短于 7 个符号时,我们会遇到错误
推荐阅读
- google-chrome - 当 Chrome 用户使用 NPAPI 插件时会发生什么?
- javascript - 平滑滚动不会使其锚定
- python - K最近邻
- javascript - JavaScript 动画延迟
- loops - 如何在 Cypress 中正确使用循环?
- python - 为 RX 6800xt 补货进行网络抓取
- mysql - Mysql:从不同的表中选择不同的相同列名
- flutter - 我可以在 FutureBuilder 中使用 Either 吗?
- ios - SwiftUI+Firestore 中的多选列表
- asp.net-core - 如何将会话 cookie 转换为持久性?