Надежное копирование файлов большого размера, отфильтрованных по расширению, между двумя дисками и сохранение каждого пути к файлу?

#powershell #robocopy #file-copying

#powershell #robocopy #копирование файлов

Вопрос:

Мне нужно скопировать файлы * .yxz (около 500 файлов по 20/30 ГБ каждый в отдельных каталогах) из v:foobar1baz.xyz, v:foobar2etc.xyz в m:foobar1baz.xyz, m:foobar2etc.xyz … dest dirs содержит другие файлы…

Я пробовал с powershell, но, к сожалению, не работает:

 $mylist = Get-ChildItem -Path "v:" -File -Recurse | Where-Object {( $_.Extension -match ".xyz" )}

$src = $mylist.FullName

$dst = $src | Split-Path
 
$dst = $dst.replace('V:','M:')

foreach ( $line in $src ) { robocopy/copy-item $line $dst }
 

Robocopy было бы лучше, но если это невозможно, я могу получить хэш файла из источника и сравнить его с местом назначения…

Я должен скопировать все файлы вручную?

Ответ №1:

Когда вы используете $dst внутри этого цикла, вы каждый раз вызываете весь массив адресатов. Вместо этого вы должны использовать первый источник с первым адресатом и так далее. Вы можете использовать что-то вроде этого:

 foreach($line in (0..(($src.length)-1))) { robocopy $src[$line] $dst[$line] }
 

 $line in (0..(($src.length)-1))
 

Это перебирает каждый элемент в массиве ‘$ src’ и устанавливает ‘$line’ равным индексу.

 { robocopy $src[$line] $dst[$line] }    
 

Это вызывает элемент в массиве, вводя индекс. например, ‘$src [0]’ вернет первый элемент в массиве.

Я не могу проверить синтаксис robocopy, но это должно устранить проблему с циклом.

Комментарии:

1. @lanteu, ты абсолютно прав, lanteu, теперь массив индексируется правильно, но, к сожалению, кажется, что Robocopy обрабатывает каждый файл как каталог, и копирование завершается неудачно… Если я использую «copy-item», я получаю эту ошибку: Cannot bind argument to parameter 'Path' because it is null. Но если я повторяю так: foreach ( $line in 0..$src.length ) { "$src[$line] $dst[$line]" } , оболочка поочередно правильно печатает исходный файл и конечный файл…

2. @Lanteu, это точная ошибка: Copy-Item : Cannot bind argument to parameter 'Path' because it is null. Line:1 char:49 foreach ( $line in 0..$src.length ) { Copy-Item $src[$line] $dst[$lin ... ~~~~~~~~~~~ CategoryInfo : InvalidData: (:) [Copy-Item], ParameterBindingValidationException FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.CopyItemCommand

3. Моя ошибка. Это должно быть ‘foreach($i in (0 ..(($src.length) -1))) {$i}’. Он попытается создать дополнительный элемент из этого массива, который не существует, поэтому выдаст ошибку. Отредактирует мой пост.

4. @lanteu, хороший снимок! Действительно спасибо lanteu! если бы я хотел добавить индикатор выполнения в этот код, write-progress командлет — правильный ли это выбор?

5. Я решил (the write.progress ) сам! $i = 0; foreach ($line in (0..(($src.length)-1))) { Copy-Item $src[$line] $dst[$line]; $i ; Write-Progress -activity "Copy in Progress . . ." -status "Copied: $i of $($src.Count)" -percentComplete (($i / $src.Count) * 100) }