【问题标题】:powershell compare file names and renamepowershell比较文件名并重命名
【发布时间】:2021-03-31 11:24:06
【问题描述】:

我有两个目录,其中都有文件。文件数不同,但文件名有些相同。例如:

C:\dwg 
AR-01-12 - file name0.dwg
AR-01-13 - file name1.dwg
AR-01-14 - file name2.dwg

C:\pdf 
AR-01-11 - file name_.pdf
AR-01-12-R1 - file name0.pdf
AR-01-13 - file name1.pdf
AR-01-14-R5 - file name2.pdf
AR-01-15-R4 - file name3.pdf

使用 powershell,如何重命名 C:\dwg 文件夹中的文件,以便将 R 缩写(来自修订版)后缀添加到来自 C:\pdf 文件夹中的文件名的名称中? 结果是:

C:\dwg 
AR-01-12-R1 - file name0.dwg
AR-01-13 - file name1.dwg
AR-01-14-R5 - file name2.dwg

我的逻辑是检查文件名的第一部分是否在 pdf 目录中,如果存在则重命名文件,留下扩展名。

【问题讨论】:

  • c:\pdf会有多个修订版吗?
  • 同一文件只有一个修订版。
  • 我发布了一个粗略的答案。让我知道它是否合适,因为我想取出一些绒毛。为了未来的读者等,社区更喜欢这样......
  • 好吧,您并没有展示您搜索、尝试过的内容以及您搜索时发生的情况。 SO规则:Provide MRE --- How to ask --- Don't ask --- Proper Topic --- Why not upload images of code/errors? --- format your post properly
  • '我的逻辑是检查文件名的第一部分是否在 pdf 目录中,如果存在则重命名文件,留下扩展名。' ---我们都喜欢帮助别人,但需要自己付出一些努力。你解释,你会做什么,但从未展示过你做了什么。说了这么多,我决定和史蒂文一样为你试一试。但是,请确保您下次联系我们,记住我们都应该遵守的规则。

标签: powershell


【解决方案1】:

我希望我是正确的。换个说法:

对于 c:\dwg 中的每个文件,在 c:\pdf 中查找一个名称相似且修订号相同的 pdf 文件。如果找到该文件,则将 c:\dwg 中的文件重命名为与 PDF 文件具有相同的基本名称。对于每个 cmets,C:\PDF 文件夹中可能有 1 个或 0 个文件与此标准匹配。显然,重命名只有在找到匹配项时才会发生。

$RefFiles = @(Get-ChildItem 'C:\pdf' -File)

Get-ChildItem 'C:\dwg' -File |
ForEach-Object{
    # Calculate a regex to match for in the reference folder.
    $RegEx = $_.BaseName -replace " - ", '-r\d{1,} - '
    $NewName = ($RefFiles.Name -match $RegEx)[0]
    
    If( $NewName ) 
    {
        # Replace extension:
        $NewName = $NewName.SubString( 0, $NewName.LastIndexOf('.') ) + $_.Extension
        Rename-Item $_.FullName $NewName -WhatIf
    }
}

解释:

  1. 对于 C:dwg 中的每个文件,我们都会计算一个正则表达式来匹配 c:\pdf 中的文件名。
  2. 使用 -match 运算符对具有先前计算的 RegEx 的数组进行操作。注意:Get-ChildItem 命令包含在数组子表达式@(...) 中。这是为了确保-match 运算符稍后的行为一致。否则,如果只有 1 个对象被返回,-match 将返回布尔值而不是匹配数组...
  3. 更换扩展名,以便我们得到正确的新名称。
  4. 然后最后执行Rename-Item命令。

如果 c:\pdf 文件夹中可能存在多个修订,您可以添加 Sort-ObjectSelect-Object 来表示获取最新修订等...

注意:RegEx 可以完善。现在它会在 -r 之后查找任意数量的数字。如果您知道最大可能的修订号,您可能会限制 -r\d{1,2},这将允许 0 -99 的 100 个可能的修订号。

【讨论】:

  • 一切都很好。是否可以修改正则表达式以选择具有AR-01-12 - file name0 - longer name.dwg 之类文件名的文件
【解决方案2】:

继续我的评论。

当然,PowerShell 允许通过多种方式执行此操作。这是一个有点不同的方法。我展示了一步一步来展示我是如何得出结果的。

# Create a file set
'AR-01-12 - file name0.dwg',
'AR-01-13 - file name1.dwg',
'AR-01-14 - file name2.dwg' | 
ForEach {New-Item -Path "d:\temp\dwg\$PSItem" -ItemType File -Force}
Get-ChildItem -Path 'd:\temp\dwg'


'AR-01-11 - file name_.pdf',
'AR-01-12-R1 - file name0.pdf',
'AR-01-13 - file name1.pdf',
'AR-01-14-R5 - file name2.pdf',
'AR-01-15-R4 - file name3.pdf' | 
ForEach {New-Item -Path "d:\temp\pdf\$PSItem" -ItemType File -Force}
Get-ChildItem -Path 'd:\temp\pdf'

# Get only needed files
Clear-Host
(
$DifferenceFiles = Get-ChildItem -Path 'd:\temp\pdf' | 
Where-Object -Property Name -Match '-R\d'
)
# Results
<#
    Directory: D:\temp\pdf

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         31-Mar-21     13:30              0 AR-01-12-R1 - file name0.pdf
-a----         31-Mar-21     13:30              0 AR-01-14-R5 - file name2.pdf
-a----         31-Mar-21     13:30              0 AR-01-15-R4 - file name3.pdf
#>

($ReferenceFiles = Get-ChildItem -Path 'd:\temp\dwg')
# Results
<#
    Directory: D:\temp\dwg

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         31-Mar-21     13:30              0 AR-01-12 - file name0.dwg   
-a----         31-Mar-21     13:30              0 AR-01-13 - file name1.dwg   
-a----         31-Mar-21     13:30              0 AR-01-14 - file name2.dwg 
#>


# Validate via string matching
Clear-Host
Get-ChildItem -Path 'd:\temp\pdf' | 
Where-Object -Property Name -Match '-R\d' | 
ForEach{
    ((Get-ChildItem -Path 'd:\temp\dwg').FullName -match ([regex]::Matches($PSItem.BaseName,$BaseNameString))) -replace $BaseNameString, ($PSItem.BaseName -replace '-R.*')
}
# Results
<#
D:\temp\dwg\AR-01-12 - file name0.dwg
D:\temp\dwg\AR-01-14 - file name2.dwg
#>

# Validate rename
Clear-Host
Get-ChildItem -Path 'd:\temp\pdf' | 
Where-Object -Property Name -Match '-R\d' | 
ForEach{
    If (($FilePath = (Get-ChildItem -Path 'd:\temp\dwg').FullName -match ([regex]::Matches($PSItem.BaseName,'..-\d+.-\d+'))))
    {
        $FileUnc = Get-ChildItem -Path $FilePath
        Rename-Item -Path $FileUnc -NewName "$($PSItem.BaseName)$($FileUnc.Extension)" -WhatIf
    }
}
# Results
<#
What if: Performing the operation "Rename File" on target "Item: D:\temp\dwg\AR-01-12 - file name0.dwg Destination: D:\temp\dwg\AR-01-12-R1 - file name0.dwg".
What if: Performing the operation "Rename File" on target "Item: D:\temp\dwg\AR-01-14 - file name2.dwg Destination: D:\temp\dwg\AR-01-14-R5 - file name2.dwg".
#>

# Execute actions
Clear-Host
Get-ChildItem -Path 'd:\temp\pdf' | 
Where-Object -Property Name -Match '-R\d' | 
ForEach{
    If (($FilePath = (Get-ChildItem -Path 'd:\temp\dwg').FullName -match ([regex]::Matches($PSItem.BaseName,'..-\d+.-\d+'))))
    {
        $FileUnc = Get-ChildItem -Path $FilePath
        Rename-Item -Path $FileUnc -NewName "$($PSItem.BaseName)$($FileUnc.Extension)" -Verbose
    }
}
# Results
<#
VERBOSE: Performing the operation "Rename File" on target "Item: D:\temp\dwg\AR-01-12 - file name0.dwg Destination: D:\temp\dwg\AR-01-12-R1 - file name0.dwg".
VERBOSE: Performing the operation "Rename File" on target "Item: D:\temp\dwg\AR-01-14 - file name2.dwg Destination: D:\temp\dwg\AR-01-14-R5 - file name2.dwg"
#>

# Review results
Get-ChildItem -Path 'd:\temp\dwg'
# Results
<#
    Directory: D:\temp\dwg

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         31-Mar-21     13:30              0 AR-01-12-R1 - file name0.dwg
-a----         31-Mar-21     13:30              0 AR-01-13 - file name1.dwg
-a----         31-Mar-21     13:30              0 AR-01-14-R5 - file name2.dwg
#>

也可以采用比较对象路线,然后使用这些结果。

Clear-Host

$ReferenceFiles = Get-ChildItem -Path 'd:\temp\pdf' | 
                  Where-Object -Property Name -Match '-R\d'

$DifferenceFiles = Get-ChildItem -Path 'd:\temp\dwg'

$CompareObjectSplat = @{
    ReferenceObject  = ($ReferenceFiles -replace '-R.*.*')
    DifferenceObject = ($DifferenceFiles -replace ' - *.*') 
    IncludeEqual     = $true
}
Compare-Object @CompareObjectSplat | 
Where-Object -Property SideIndicator -eq '=='
# Results
<#
AR-01-12    ==           
AR-01-14    == 
#>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多