【问题标题】:Renaming script in PowerShell在 PowerShell 中重命名脚本
【发布时间】:2018-10-05 14:58:23
【问题描述】:

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

【问题讨论】:

  • dirGet-ChildItem 的别名。查看帮助(链接),了解如何在枚举中包含/排除项目的详细信息。

标签: powershell


【解决方案1】:

我会在您的代码中更改一些内容。一方面,每次更改文件名时,您都可以致电 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)'"
        }
    }

【讨论】:

  • 我不太清楚为什么,但是当我尝试运行它时,它关闭了。顶部有一些错误内容,但窗口关闭得太快,我无法阅读。我省略了文件路径的文件夹部分以测试它是否会跳过 .ps1。阅读您的代码,在我看来它可以正常工作,所以也许这是我的目标?
  • 它至少应该在失败之前询问用户输入不是吗?抱歉,我对 powershell 很陌生。我只用 python 编写过简单的游戏。
  • 尝试从 Powershell ISE 运行它。从编辑器中发现错误要容易得多
  • 缺少一个“}”。通常的罪魁祸首 :) 感谢您的帮助西奥!
  • 啊,很高兴听到这很简单?
猜你喜欢
  • 2011-10-25
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-03
相关资源
最近更新 更多