根据从CSV获取的匹配ID重命名文件

时间:2016-09-02 17:56:10

标签: powershell

我有以下csv列表(实际上是1000行):

needle,code
123456,AB
121212,BB
33333333,CVV

我有一个包含pdf文件的目录(实际上是1000s):

dsadsadsa.343222.dsads23213jkjl.saddsa.pdf
dsadsadsa.123456.dsads23213jkjl.saddsa.pdf
dsadsadsa.111111.dsads23213jkjl.saddsa.pdf
dsadsadsa.33333333.dsads23213jkjl.saddsa.pdf
dsadsadsa.33333333.fsdgdsfdsfdsf.dsad.pdf

对于csv中的每个针:

  • 我必须查看是否有包含该针的pdf(可能有0个或更多匹配)
  • 如果匹配,我必须将相应的代码添加到名称

例如,123456匹配,33333333匹配,因此我必须重命名为:

AB.dsadsadsa.123456.dsads23213jkjl.saddsa.pdf
CVV.dsadsadsa.33333333.dsads23213jkjl.saddsa.pdf
CVV.dsadsadsa.33333333.fsdgdsfdsfdsf.dsad.pdf

由于我对Powershell很陌生,我开始迭代文件:

Get-ChildItem -Path "R:\files" | Where-Object { $_.Name -like "$needle" } | %{ Rename-Item -LiteralPath $_.FullName -NewName ({0}_{1} -f $code,$_.Name) }

显然这不起作用,因为我没有填充$needle$code

你能帮帮我吗?

  • 逐行阅读csv,填充$needle$code
  • 并相应地重命名文件?

任何帮助都会非常感激

3 个答案:

答案 0 :(得分:2)

从示例文件名中,针码始终位于第一个点之后,后跟另一个点。如果你可以依赖它,那么你可以构建一个哈希表映射针 - >代码+点,从每个文件名中删除该位并在哈希表中查找。

如果针代码与哈希表中的任何内容不匹配,它将返回$ null,并且NewName将与当前名称相同;快速测试说,在这种情况下,Rename-Item不做任何事情。

$pairs = @{}
Import-CSV .\data.csv | ForEach-Object { $pairs[$_.needle] = $_.code+"." }

Get-ChildItem | Rename-Item -NewName { $pairs[$_.Name.Split('.')[1]] + $_.Name } -WhatIf

答案 1 :(得分:0)

这应该可行,或至少让你开始。

$entries = Import-csv .\file.csv


ForEach ($entry in $entries){
    $filesToRename = Get-ChildItem c:\pathToYourFiles | Where Name -like "*$($entry.needle)*"     

    ForEach ($file in $filesToRename ){

        Rename-Item -Path $file.FullName -NewName "$($entry.code)$($file.BaseName)" -WhatIf

    }

}

首先,我们导入您的CSV并将其命名为$entries

然后我们逐步浏览每个$entry并提取此目录中所有文件的列表。我希望每次都这样做,以防文件名在运行时发生变化。我们过滤此文件列表仅包括与针的值匹配的文件。 (我也喜欢可爱的属性名称,针和干草堆)。我们称这些匹配的文件为$filesToRename

接下来,我们逐步完成每个匹配的$file并在其上运行Rename-Item,提供完整的文件名并指定所需的-NewName

我把它放在-WhatIf模式下,这样你就可以安全地看到在运行它之前会发生什么。

如果你感到高兴,请删除-WhatIf并与上帝同行。

答案 2 :(得分:0)

我想我会尽量避免必须通过在彼此之间嵌套ForEach循环来拉动目录列表数百万次。我要做的是从你的第一个CSV中创建一个哈希表,然后从针中创建一个RegEx模式。然后获取目录列表,通过RegEx匹配运行每个文件,并根据哈希表中匹配的字符串条目重命名该文件。

$Needles = Import-CSV C:\Path\To\File.csv
[regex]$RegExPattern = '^.*(' + (($Needles.needle|%{[regex]::Escape($_)}) -join '|') + ').*$'

$Hash = @{}
$Needles|%{$Hash.Add($_.Needle,$_.code)}



ForEach($File in (Get-ChildItem R:\files)){
    $RegExPattern.Matches($File.Name)|Rename-Item -path $File.FullName -NewName { $Hash["$($_[0].Groups[1])"]+'.'+$File.Name }
}