带文件检查和重命名的单行管道循环

问题描述 投票:0回答:1

所以我试图重命名一堆MSSQL备份,如下所示:

DBName_backup_2017_12_20_564451321_567987465.bak

像某样的东西

DBName.bak

但也有一个安全检查,以确保如果已经采取DBName.bak它将做DBName_1.bak。其中1将是增量变量,直到存在有效的未使用文件名。

我能够使用以下代码执行此操作:

Get-ChildItem *_*.bak | % { 
    # Set the new name, replace everything after the first underscore '_' with
    # '.bak'
    $newName = &{$_.Name -replace $_.Name.Substring($_.Name.IndexOf("_")), '.bak'}

    # Check if new name exists
    for ($cnt = 1; (Test-Path $newName) -eq $true; $cnt++) { 
        # If it already exists add '_' and a number check again until unused
        # filename is found
        $newName = &{$newName -replace '.bak', "_$cnt.bak"} 
    }

    # Rename file to new filename. Uncomment WhatIf for testing.
    Rename-Item -Path $_ -NewName $newName #-WhatIf
}

我现在要做的是将它与管道连接起来,但我没有运气。特别是使用Test-Path检查运行循环。有谁知道我怎么能这样?

powershell
1个回答
1
投票

简单:

$cnt = 0; Get-ChildItem *_*.bak | Rename-Item -NewName {
    ($_.BaseName -replace '_.*', '_') + $script:cnt++ + $_.Extension
} -WhatIf

如果你只想(重新)对具有重复数据库名称的文件进行编号,那么你就无法真正对这些文件进行单行处理。你需要这样的东西:

Get-ChildItem *_*.bak | ForEach-Object {
    $basename = $_.BaseName -replace '_.*'
    $newname  = $basename + $_.Extension
    $script:cnt = 1
    while (Test-Path $newname) {
        $newname = $basename + '_' + $script:cnt++ + $_.Extension
    }
    Rename-Item -NewName $newname -WhatIf
}

但是,在PowerShell中,您可以使用换行符和分号分隔语句,因此您仍然可以将上述所有内容合并为一行。像这样:

Get-ChildItem *_*.bak | ForEach-Object {$basename = $_.BaseName -replace '_.*'; $newname  = $basename + $_.Extension; $script:cnt = 1; while (Test-Path $newname) {$newname = $basename + '_' + $script:cnt++ + $_.Extension}; Rename-Item -NewName $newname -WhatIf}

但是,我通常不建议这样做,因为它会使代码难以阅读和调试。

无论哪种方式,在验证重命名后根据需要移除鸡开关。

© www.soinside.com 2019 - 2024. All rights reserved.