在PowerShell中重命名脚本

时间:2018-10-05 14:58:24

标签: powershell

我正在尝试编写脚本以使用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?

1 个答案:

答案 0 :(得分:2)

我会在您的代码中进行一些更改。一方面,您可以在一次调用中对文件名的每次更改调用dirGet-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)'"
        }
    }