我正在尝试编写脚本以使用PowerShell从某个文件夹中的文件名中删除字符。它提示用户输入要从正面,背面和特定字符串中删除多少个字符。
# Prompt User how many characters in the front they want removed
$FrontRemove = Read-Host 'Enter how many characters you want removed from the front'
# Prompt user how many characters in the back they want removed
$BackRemove = Read-Host 'Enter how many characters you want removed from the back'
# Prompt user for string to be removed
$MiddleRemove = Read-Host 'Enter a string you want removed from the file name'
dir | Rename-Item -NewName{$_.name.substring(0,$_.BaseName.length-$BackRemove)}
dir | Rename-Item -NewName{$_.name.substring($FrontRemove)}
dir | Rename-Item -NewName{$_.name -replace "$MiddleRemove", ""}
我当前遇到的问题是它正在删除这些文件的扩展名,并且还在重命名脚本本身。我将如何保留文件扩展名并排除.ps1?
答案 0 :(得分:2)
我会在您的代码中进行一些更改。一方面,您可以在一次调用中对文件名的每次更改调用dir
(Get-ChildItem
)。
此外,它缺乏任何形式的检查来查看用户输入的内容是否可以针对Get-ChildItem
返回的每个文件进行。
未指定路径的Get-ChildItem
将在当前位置中搜索项目。如果那不是您想要的,也许像下面的代码中那样设置路径会更安全。
$folder = '<ENTER THE PATH TO THE FOLDER WHERE THE FILES TO RENAME ARE HERE>'
# Prompt User how many characters in the front they want removed --> number
[int]$FrontRemove = Read-Host 'Enter how many characters you want removed from the front'
# Prompt user how many characters in the back they want removed --> number
[int]$BackRemove = Read-Host 'Enter how many characters you want removed from the back'
# Prompt user for string to be removed --> string
[string]$MiddleRemove = Read-Host 'Enter a string you want removed from the file name'
# Since we are using the -replace function, which is using Regular Expression replacement,
# we need to make sure all 'special' characters in the string are escaped.
if (![string]::IsNullOrEmpty($MiddleRemove)) {
$MiddleRemove = [Regex]::Escape($MiddleRemove)
}
Get-ChildItem -Path $folder -File | Where-Object {$_.Name -notlike '*.ps1'} |
ForEach-Object {
$directory = $_.DirectoryName # or [System.IO.Path]::GetDirectoryName($_.FullName) or use Split-Path $_.FullName -Parent
$filename = $_.BaseName # or [System.IO.Path]::GetFileNameWithoutExtension($_.Name)
$extension = $_.Extension # or [System.IO.Path]::GetExtension($_.Name)
# test user input and remove/replace only if possible
if ($FrontRemove -gt 0 -and $FrontRemove -lt $filename.Length) {
$filename = $filename.Substring($FrontRemove)
}
if ($BackRemove -gt 0 -and $BackRemove -lt $filename.Length) {
$filename = $filename.Substring(0, $filename.Length - $BackRemove)
}
if (![string]::IsNullOrEmpty($MiddleRemove)) {
$filename = $filename -replace $MiddleRemove, ''
}
# now see if we still have a name left and if indeed the filename has changed
if (![string]::IsNullOrEmpty($filename) -and $filename -ne $_.BaseName) {
# re-append the extension of the file
if (![string]::IsNullOrEmpty($extension)) { $filename += $extension }
# join it with the directory to become a complete path and filename
$newname = Join-Path -Path $directory -ChildPath $filename
Rename-Item -LiteralPath $_.FullName -NewName $newname -Force
}
else {
Write-Warning "The options you entered would remove the entire filename. Action skipped on '$($_.FullName)'"
}
}