Переименование файлов в каталоге с использованием новых имен из файла csv

Мне нужна помощь в создании сценария, который может переименовывать все файлы, содержащиеся в каталоге, в таблицу, на которую ссылается файл csv. Например, у меня есть папка со случайными именами файлов, а также файл csv с текущими именами файлов в столбце A и тем, на какое фактическое имя файла следует изменить в столбце B.

Я думал об использовании чего-то вроде:

get-childitem *pdf -force | foreach { rename-item $_ $_.Name.Replace((Import-Csv -path .\List.csv).filename, (Import-Csv -Path .\List.csv).newfilename) }

Обратите внимание, что имя файла и новое имя файла относятся к столбцам A и B соответственно.

На самом деле ничего не происходит, когда я запускаю этот скрипт. Я новичок в powershell, поэтому я пришел к пределу своих знаний о том, как выполнить эту задачу. Любая помощь будет принята с благодарностью!

Спасибо вам всем!


person Ric.Mart    schedule 30.12.2019    source источник
comment
Содержит ли файл CSV полные пути к файлам или только имена файлов?   -  person AdminOfThings    schedule 30.12.2019
comment
@AdminOfThings только имена файлов, но я мог бы изменить электронную таблицу, чтобы она также содержала пути к файлам (как для текущих, так и для новых имен).   -  person Ric.Mart    schedule 30.12.2019
comment
Отвечает ли это на ваш вопрос? Powershell - найти файл по имени файла и переименовать на основе CSV   -  person Theo    schedule 30.12.2019
comment
@Theo Не совсем, я просмотрел этот пост, и ответы на самом деле не очень помогли моему текущему сценарию.   -  person Ric.Mart    schedule 03.01.2020


Ответы (2)


Вы можете сделать следующее, если находитесь в каталоге, содержащем целевые файлы и файл CSV. Это предполагает, что в вашем CSV-файле есть заголовки с именами filename и newfilename.

$TargetDir = Resolve-Path -Path .
Import-Csv -Path .\List.csv | Foreach-Object {
    $Src = Join-Path -Path $TargetDir -ChildPath $_.filename
    $Dst = Join-Path -Path $TargetDir -ChildPath $_.newfilename
    Rename-Item -Path $Src -NewName $Dst
}

Если целевым каталогом является другое место, вы можете просто изменить операторы Join-Path, чтобы использовать -Path.

$TargetDir = 'c:\folder'
Import-Csv -Path .\List.csv | Foreach-Object {
    $Src = Join-Path -Path $TargetDir -ChildPath $_.filename
    $Dst = Join-Path -Path $TargetDir -ChildPath $_.newfilename
    Rename-Item -Path $Src -NewName $Dst
}

Примечание. Если файл CSV не содержит заголовков, вам нужно будет либо использовать переключатель -Header в Import-Csv, как в полезный ответ Гленна или добавьте заголовки столбцов в CSV.

person AdminOfThings    schedule 30.12.2019
comment
Ответ лучше моего. - person Glenn; 30.12.2019
comment
В обоих ответах есть полезные элементы. - person AdminOfThings; 30.12.2019
comment
Извините, джентльмены, должно быть я что-то делаю не так или что-то не так в электронной таблице. Я запустил этот скрипт и получил следующее сообщение об ошибке: Rename-Item: невозможно переименовать элемент в папке «C:\Users\ZZZZZZ\Desktop\Name Testing», поскольку он используется. В строке: 4 символа: 5 + Переименовать-Элемент -Путь $Src -НовоеИмя $Dst - person Ric.Mart; 30.12.2019
comment
@ Ric.Mart Я внес некоторые изменения в код, чтобы сделать работу с двумя подходами более похожей. - person AdminOfThings; 30.12.2019

Предполагая, что в .csv нет заголовка и он содержит только имена файлов, это может сработать для вас:

# Only import the CSV once
$csvData = Import-Csv .\List.csv -Header "Old","New"

# Remove the -WhatIf after testing
Get-ChildItem | ForEach-Object { 
    $file = $_
    $csvData | Where-Object { 
        $_.Old -eq $file.Name 
    } | ForEach-Object { 
        Rename-Item -Path $file -NewName $_.New -WhatIf 
    } 
}

Или более краткая реализация:

$csvData = Import-Csv .\List.csv -Header "Old","New"
dir | %{ $file = $_; $csvData | ?{ $_.Old -eq $file.Name } | %{ Rename-Item -Path $file -NewName $_.New -WhatIf } }
person Glenn    schedule 30.12.2019
comment
Я запустил скрипт с параметром -whatif и без него, и похоже, что ничего не произошло. Должен ли я включать заголовки, такие как Old и New? - person Ric.Mart; 30.12.2019
comment
в моем последнем редактировании была ошибка (было %{ $_.Old -eq $file.Name } вместо ?{ $_.Old -eq $file.Name }). Если вы по-прежнему не видите никаких выходных данных, возможно, он не находит соответствия для имен файлов. - person Glenn; 30.12.2019
comment
Вот скриншот примера с некоторыми тестовыми данными, которые я собрал вместе: i.imgur.com/6nvOBjc.png - person Glenn; 30.12.2019