根据导入的 CSV 替换文件名中的单词

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

我有一系列 .pdf 文件,其中名称包含旧文件编号,我想将其转换为新文件编号。但是,我只想更改文件编号部分,不想重命名整个文档。文档名称也不一致,因此我不能将整个路径放入 .csv 中并这样做。

例如,基于以下.csv:

旧名称,新名称
A12345,A98765
A00645,A39502

以下文件:

A12345 终止函.pdf
A00645 通讯.pdf

会变成:

A98765 终止函.pdf
A39502 信件

我当前使用以下脚本来删除或替换给定目录中文件名称中的单个单词(在本示例中,我将 - Copy 替换为空):

$path = "C:\path"
$filter = '*.pdf'
get-childitem -path $path -filter $filter | 
 rename-item -newname {$_.name -replace '- Copy',''}

我正在尝试解决这个问题,构建一些以相同方式工作的东西,但从 .csv 中提取替换单词,这样我就可以一次进行多个替换。我不确定我是否在搜索中没有使用正确的语法,但我一直在寻找重命名整个文档、更改 .csv 中的单词等的方法。我本质上只是想进行查找并更换。

powershell csv
1个回答
0
投票
oldname

,然后使用

 替换为匹配评估器
替换为脚本块(同样的事情,后者仅适用于较新的版本PowerShell),您可以从给定的匹配中获得 newname (
.Value
)。
逻辑如何进行的一个小例子:

# this is a dictionary where you have `oldname` and `newname` $map = @{ A12345 = 'A98765' A00645 = 'A39502' } # the OR pattern $replacePattern = [regex]::new( 'A12345|A00645', [System.Text.RegularExpressions.RegexOptions] 'Compiled, IgnoreCase') # the replacement logic 'A12345 Termination Letter.pdf', 'A00645 Correspondence.pdf' | ForEach-Object { $replacePattern.Replace($_, { $map[$args[0].Value] }) } # Outputs: # A98765 Termination Letter.pdf # A39502 Correspondence.pdf

在实际代码中,
$map

是动态构造的,但其余代码类似,但是应该检查正则表达式模式是否与文件名匹配,否则您将尝试重命名具有相同名称的文件在旧版本中失败:

# this dynamically creates dictionary with `oldname` and `newname`
$map = @{}
Import-Csv 'the\path\toMyRenamingFiles.csv' |
    ForEach-Object { $map[$_.oldname] = $_.newname }

# this creates an OR pattern like 'A12345|A00645|...|...|etc'
$replacePattern = [regex]::new(
    $map.Keys.ForEach({ [regex]::Escape($_) }) -join '|',
    [System.Text.RegularExpressions.RegexOptions] 'Compiled, IgnoreCase')

$path = 'C:\path'
$filter = '*.pdf'
Get-ChildItem -Path $path -Filter $filter |
    Where-Object { $replacePattern.IsMatch($_.Name) } |
    Rename-Item -NewName { $replacePattern.Replace($_.Name, { $map[$args[0].Value] }) }

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