Копировать имена файлов из одной папки в другую, сохраняя оригинальные расширения
Мне нужна помощь с копированием имен файлов (не самих файлов) с диска C на диск D. Мне удалось найти следующий код powershell в Интернете:
$names = @()
$getPath = "C:\MyFiles"
$setPath = "D:\MyFiles"
Get-ChildItem $getPath |
Foreach-object{
$names += $_
}
$i = 0
Get-ChildItem $setPath |
Foreach-object{
Rename-Item -Path $_.FullName -NewName $names[$i]
$i++
}
Этот код успешно переименовывает / копирует все имена файлов из C:\MyFiles
в D:\MyFiles
строго по соответствующим позициям (показатели в перечислении).
Тем не менее, он также обновляет расширения, например:
C:\MyFiles\myfile.txt
переименовывает D:\MyFiles\thisfile.docx
в D:\MyFiles\myfile.txt
Есть ли способ отредактировать код Powershell, чтобы переименовать только базу имени файла (например, myFile
) при сохранении расширений целевых файлов (например, .docx
)?
Чтобы C:\MyFiles\myfile.txt
переименовывает D:\MyFiles\thisfile.docx
в D:\MyFiles\myfile.docx
, с использованием
1 ответ
Звучит так, как будто вы хотите переименовать файлы в целевом каталоге по месту, основываясь на соответствующих файлах в исходном каталоге - при сохранении расширений файлов целевого каталога:
$getPath = "C:\MyFiles"
$setPath = "D:\MyFiles"
$sourceFiles = Get-ChildItem -File $getPath
$iRef = [ref] 0
Get-ChildItem -File $setPath |
Rename-Item -NewName { $sourceFiles[$iRef.Value++].BaseName + $_.Extension }
Для предварительного просмотра полученных имен файлов добавьте
-WhatIf
кRename-Item
вызов..BaseName
собственность[System.IO.FileInfo]
объекты выводятсяGet-ChildItem
возвращает часть имени файла без расширения.$_.Extension
извлекает существующее расширение входного файла (т. е. целевого файла), включая ведущие.
Обратите внимание, что блок скрипта (
{ ... }
) перешел кRename-Item
создает дочернюю переменную области видимости, поэтому вы не можете увеличивать переменную непосредственно в области действия вызывающей стороны (при этом каждый раз будет создаваться новая копия такой переменной с исходным значением); следовательно,[ref]
экземпляр создается для косвенного хранения номера, который дочерняя область может затем изменить с помощью.Value
имущество.
Вот полный пример:
Примечание. Хотя в этом примере используются похожие имена файлов и одинаковые расширения, код работает в общем, с любыми именами и расширениями.
# Determine the temporary paths.
$getPath = Join-Path ([System.IO.Path]::GetTempPath()) ('Get' + $PID)
$setPath = Join-Path ([System.IO.Path]::GetTempPath()) ('Set' + $PID)
# Create the temp. directories.
$null = New-Item -ItemType Directory -Force $getPath, $setPath
# Fill the directories with files.
# Source files: "s-file{n}.source-ext"
"--- Source files:"
1..3 | % { New-Item -ItemType File (Join-Path $getPath ('s-file{0}.source-ext' -f $_)) } |
Select -Expand Name
# Target files: "t-file{n}.target-ext"
"
---- Target files:"
1..3 | % { New-Item -ItemType File (Join-Path $setPath ('t-file{0}.target-ext' -f $_)) } |
Select -Expand Name
# Get all source names.
$sourceFiles = Get-ChildItem -File $getPath
# Perform the renaming, using the source file names, but keeping the
# target files' extensions.
$i = 0; $iVar = Get-Variable -Name i
Get-ChildItem -File $setPath |
Rename-Item -NewName { $sourceFiles[$iVar.Value++].BaseName + $_.Extension }
"
---- Target files AFTER RENAMING:"
Get-ChildItem -Name $setPath
# Clean up.
Remove-Item -Recurse $getPath, $setPath
Вышеуказанные выходы:
--- Source files:
s-file1.source-ext
s-file2.source-ext
s-file3.source-ext
---- Target files:
t-file1.target-ext
t-file2.target-ext
t-file3.target-ext
---- Target files AFTER RENAMING:
s-file1.target-ext
s-file2.target-ext
s-file3.target-ext
Обратите внимание, что целевые файлы теперь имеют базовые имена исходных файлов (s-file*
), но исходные расширения целевых файлов (.target-ext
).