Powershell 在多次迭代中重命名文件

Powershell 在多次迭代中重命名文件,powershell,refactoring,Powershell,Refactoring,我有一个文件夹,里面有不同数量的文件,都是相同的形式,我从共享站点批量下载 下载的文件都使用类似的模式自动命名,但是,这不是我的服务器所需要的结束模式。下面的代码完成了任务,但看起来很笨拙,我的直觉告诉我有更好的方法在一个文件名上写多个替换。请帮我重新编码 我尝试了多个管道,问题似乎在于,一旦在第一次迭代中重命名了文件,之后我的所有引用都不起作用。因此,在替换之后,我需要为新迭代创建一个新变量 $pathToRFIs = 'C:\Users\user\Downloads\*.pdf' $path

我有一个文件夹,里面有不同数量的文件,都是相同的形式,我从共享站点批量下载

下载的文件都使用类似的模式自动命名,但是,这不是我的服务器所需要的结束模式。下面的代码完成了任务,但看起来很笨拙,我的直觉告诉我有更好的方法在一个文件名上写多个替换。请帮我重新编码

我尝试了多个管道,问题似乎在于,一旦在第一次迭代中重命名了文件,之后我的所有引用都不起作用。因此,在替换之后,我需要为新迭代创建一个新变量

$pathToRFIs = 'C:\Users\user\Downloads\*.pdf'
$path2ToRFIs = 'C:\Users\user\Downloads'

$text = [System.Threading.Thread]::CurrentThread.CurrentCulture.TextInfo


$lowerRFIs = gci -path $pathToRFIs -filter *rfi*
$lowerRFIs | ren -newname {"$($text.ToTitleCase($_.BaseName))$($_.Extension)"}

$properRFIs = gci -path $pathToRFIs -filter *rfi*
$properRFIs | ren -newname {$_.name -replace '___',' & '}

$andRFIs = gci -path $pathToRFIs -filter *rfi*
$andRFIs | ren -newname {$_.name -replace '_',' '}

$spaceRFIs = gci -path $pathToRFIs -filter *rfi*
$spaceRFIs | ren -newname {$_.name -replace 'Encinitas Beach Resort-Rfi ','RFI 00'}

$RFIs = gci -path $pathToRFIs  -filter *RFI*
$RFIs | ren -newname {$_.name -replace '^(.*?)-', '$1_'}

$RFIs_ = gci -path $pathToRFIs -filter *RFI*
$RFIs_ | ren -newname {$_.name.substring(0,$_.name.length-17)}

$finalRFIs = gci -path $path2ToRFIs *"RFI 0"*
$finalRFIs | ren -newname {$_.fullname + ".pdf"}
作为参考,我收到的文件如下:

"encinitas beach resort-rfi 31-public water closets-201903221442.pdf"
所需的最终结果名称为:

"RFI 0031_Public Water Closets.pdf"

通过按建议使用
ForEach对象
,您可以使用regex
-match
来捕获所需文件名的部分。(编号和主题)

然后,在循环中进行如下重命名操作:

$pathToRFIs = 'C:\Users\user\Downloads'

Get-ChildItem -Path $pathToRFIs -Filter '*rfi*' -File | ForEach-Object {
    if ($_.BaseName -match '.*rfi\s+(?<number>\d+)-(?<subject>.*)\s*-\d+$') {
        $subject = (Get-Culture).TextInfo.ToTitleCase($matches['subject']) -replace '___',' & ' -replace '_', ' '
        $newName = 'RFI {0:D4}_{1}{2}' -f ([int]$matches['number']), $subject, $_.Extension

        $_ | Rename-Item -NewName $newName -WhatIf
    }
}

通过按建议使用
ForEach对象
,您可以使用regex
-match
来捕获所需文件名的部分。(编号和主题)

然后,在循环中进行如下重命名操作:

$pathToRFIs = 'C:\Users\user\Downloads'

Get-ChildItem -Path $pathToRFIs -Filter '*rfi*' -File | ForEach-Object {
    if ($_.BaseName -match '.*rfi\s+(?<number>\d+)-(?<subject>.*)\s*-\d+$') {
        $subject = (Get-Culture).TextInfo.ToTitleCase($matches['subject']) -replace '___',' & ' -replace '_', ' '
        $newName = 'RFI {0:D4}_{1}{2}' -f ([int]$matches['number']), $subject, $_.Extension

        $_ | Rename-Item -NewName $newName -WhatIf
    }
}

答案是肯定的。请注意,这只是对您已经完成的工作的转换。通过使用单个调用
重命名项
,并在
foreach对象
上使用
foreach
,它也将大大加快速度

$text = [System.Threading.Thread]::CurrentThread.CurrentCulture.TextInfo
foreach ($file in Get-ChildItem -Path $Env:USERPROFILE\Downloads\*.pdf -Filter *rfi*) {
    $rename = $text.ToTitleCase($file.BaseName) + $file.Extension
    $rename = $rename -replace '_{3}', ' & ' -replace '_', ' ' -replace 'Encinitas Beach Resort-Rfi ', 'RFI 00'
    $rename = $rename -replace '^(.*?)-', '$1_'
    $rename = $rename.Substring(0, $rename.Length - 17) + '.pdf'
    $file | Rename-Item -NewName $rename
}
一个正则表达式来规定所有的规则,减去大小写:


答案是肯定的。请注意,这只是对您已经完成的工作的转换。通过使用单个调用
重命名项
,并在
foreach对象
上使用
foreach
,它也将大大加快速度

$text = [System.Threading.Thread]::CurrentThread.CurrentCulture.TextInfo
foreach ($file in Get-ChildItem -Path $Env:USERPROFILE\Downloads\*.pdf -Filter *rfi*) {
    $rename = $text.ToTitleCase($file.BaseName) + $file.Extension
    $rename = $rename -replace '_{3}', ' & ' -replace '_', ' ' -replace 'Encinitas Beach Resort-Rfi ', 'RFI 00'
    $rename = $rename -replace '^(.*?)-', '$1_'
    $rename = $rename.Substring(0, $rename.Length - 17) + '.pdf'
    $file | Rename-Item -NewName $rename
}
一个正则表达式来规定所有的规则,减去大小写:

  • 不需要中间变量
  • 也不是每一个对象
  • 所有的转化蛋白都可以彼此粘附在一起,在这里有一个背勾
  • 和一个尾随的
    -Whatif
    ,仅显示发生的情况,如果

如果输出看起来正常,请删除
-WhatIf

  • 不需要中间变量
  • 也不是每一个对象
  • 所有的转化蛋白都可以彼此粘附在一起,在这里有一个背勾
  • 和一个尾随的
    -Whatif
    ,仅显示发生的情况,如果


如果输出看起来正常,请删除
-WhatIf

,而不是直接通过管道连接到Rename Item cmdlet,您可以通过管道连接到
ForEach Object
cmdlet,然后将最后一次替换以外的所有操作作为一系列链式的
-replace
操作执行。这将为您节省一些时间和CPU周期,因为通过管道发送内容需要资源。[grin]然后,最后,执行last
-replace
,并在单个
Rename\u Item
调用中使用结果。您可以通过管道连接到
ForEach Object
cmdlet,而不是直接连接到Rename Item cmdlet,然后将除last replace之外的所有操作作为一系列链式的
-replace
操作来执行。这将为您节省一些时间和CPU周期,因为通过管道发送内容需要资源。[grin]然后,最后,执行最后一个
-替换
,并在单个
重命名项目
调用中使用结果。您是否写出了正则表达式解释,或者是否有相应的工具?如果真是这样的话,那真是太快了you@TheIncorrigible1我总是用RegexBuddy。非常适合尝试正则表达式,之后您也可以获得这些详细信息。(只需对其进行一些格式化)。但不是免费的。缺少一些转换(示例中未出现)<代码>'
=>
'&'
'
=>
'
=>
'
@LotPings被很好地发现了。不过很容易解决;)@西奥:谢谢你的regex介绍!我只是尝试了你的代码,但是在PowerShell ISE中点击run之后,终端只是显示代码,似乎什么都没做。有什么想法吗?你写了正则表达式的解释了吗?或者有什么工具可以解释吗?如果真是这样的话,那真是太快了you@TheIncorrigible1我总是用RegexBuddy。非常适合尝试正则表达式,之后您也可以获得这些详细信息。(只需对其进行一些格式化)。但不是免费的。缺少一些转换(示例中未出现)<代码>'
=>
'&'
'
=>
'
=>
'
@LotPings被很好地发现了。不过很容易解决;)@西奥:谢谢你的regex介绍!我只是尝试了你的代码,但是在PowerShell ISE中点击run之后,终端只是显示代码,似乎什么都没做。有什么想法吗?谢谢!这正是我正在寻找的,我只是不知道什么是正确的语法。如果答案解决你的问题,或者你觉得它们有用,你应该考虑和/或谢谢!这正是我正在寻找的,我只是不知道什么是正确的语法。如果答案解决了你的问题,或者你发现它们有帮助,你应该考虑和/或。
## Q:\Test\2019\03\29\SO_55424102.ps1
$pathToRFIs = 'C:\Users\user\Downloads\*.pdf'

$text = [System.Threading.Thread]::CurrentThread.CurrentCulture.TextInfo

Get-ChildItem -Path $pathToRFIs -Filter *rfi* |
    Rename-Item -NewName {($text.ToTitleCase($_.BaseName) `
       -replace '___',' & ' `
       -replace '_',' ' `
       -replace 'Encinitas Beach Resort-Rfi ','RFI 00' `
       -replace '(?<=^[^-]*)-', '_' `
       -replace '-\d{12}$')+$_.Extension} -WhatIf
WhatIf: Ausführen des Vorgangs "Datei umbenennen" für das 
Ziel "Element: Q:\Test\2019\03\29\encinitas beach resort-rfi 31-public water closets-201903221442.pdf 
         Ziel: Q:\Test\2019\03\29\RFI 0031_Public Water Closets.pdf".