искать и копировать файлы из структуры каталогов, читая текстовый файл

1

У меня есть папка со многими подпапками и файлами в них. У меня есть текстовый файл с именами файлов, которые я хочу скопировать в отдельную папку назначения. Имена файлов в текстовом файле не содержат информации о пути.

В папке назначения я хочу, чтобы файл и его структура папок были воссозданы. Есть ли быстрый сценарий для этого? или инструмент? Я на винде.

Regmi
источник
1
Отправная точка для вас, чтобы продолжить, но это тривиально для пакетного сценария, как я .... FOR /F "USEBACKQ TOKENS=*" %A IN ("C:\Folder\Path\TextFile.txt") DO ECHO %~A, , , ss64.com/nt/for_cmd.html , , , Прочтите некоторые из моих ответов, которые могут быть применимы, просто выберите их и прочитайте, поскольку я уверен, что помогал с этим раньше кому-то: superuser.com/search?q=user%3A510662+body%3A+for+%2Ff
Pimp Juice IT

Ответы:

2

Следующий скрипт PowerShell должен делать то, что вы хотите.

Измените первые три переменные в соответствии с вашей средой.

## Q:\Test\2018\06\28\SU_1334840.ps1
#Requires -Version 3

# get files to copy from file in same foler
$FileList = Get-Content '.\FileList.txt'
$BaseSrc = 'X:\Source\path\'
$BaseDst = 'Y:\Destination\path\'

ForEach ($File in $FileList){
   ForEach ($Find in (Get-ChildItem $BaseSrc$File -File -Recurse)) {
       $DestFile = Join-Path $BaseDst ($Find.FullName.Replace($BaseSrc,'') )
       $DestDir = Split-Path $DestFile
       If (!(Test-Path $DestDir)){ MD $DestDir |Out-Null}
       # "Copying {0} to {1}" -f $Find.FullName,$DestFile
       Copy-Item $Find.FullName $DestFile
    }
}

Чтобы увидеть, что происходит во время работы скрипта, удалите # до "Copying...

Сценарий требует как минимум PowerShell версии 3

В зависимости от размера вашего списка / количества файлов и подкаталогов в дереве исходных текстов, этот немного другой подход может быть быстрее.

## Q:\Test\2018\06\28\SU_1334840_2.ps1
#Requires -Version 3

# get files to copy from file in same foler
$FileList = Get-Content '.\FileList.txt'
$BaseSrc = 'X:\Source\path\'
$BaseDst = 'Y:\Destination\path\'

ForEach ($File in (Get-ChildItem $BaseSrc -File -Recurse)) {
    If ($File.Name -in $FileList) {
       $DestFile = Join-Path $BaseDst ($File.FullName.Replace($BaseSrc,'') )
       $DestDir = Split-Path $DestFile
       If (!(Test-Path $DestDir)){ MD $DestDir |Out-Null}
       "Copying {0} to {1}" -f $File.FullName,$DestFile
       Copy-Item $File.FullName $DestFile
    }
}

Пример вывода:

> . Q:\Test\2018\06\28\SU_1334840.ps1
Copying C:\sys\7z.dll to A:\Test\sys\7z.dll
Copying C:\sys\7z.exe to A:\Test\sys\7z.exe
Copying C:\sys\ClipBoard.exe to A:\Test\sys\ClipBoard.exe
Copying C:\sys\ClipBoard.txt to A:\Test\sys\ClipBoard.txt
Copying C:\sys\DUMPHEX.EXE to A:\Test\sys\DUMPHEX.EXE
LotPings
источник
это работает, по какой-то причине скрипт не находит некоторые файлы, такие как "00-00-00_0001 0894 0007861.JPG". Есть ли способ перечислить, какие файлы не были найдены? (Заметили ли вы пробел между открытием кавычек и первым 0 в этом имени файла ?!
Regmi
Мы нашли решение для такого файла. Мы добавили все имена файлов в текстовом файле с *. Спасибо!
Regmi
Спасибо за отзыв, просто из интереса - какой вариант был быстрее в ваших попытках?
LotPings
Первый был лучше на самом деле, и в итоге я его использовал! У меня есть около 17k имен файлов в файле FileList.txt, а машина - 16G RAM, Win 2012 Server
Regmi
Ничего себе, исходя из этих цифр, я бы ожидал, что последний лидирует, но кеширование файлового сервера, похоже, перевернуло его.
LotPings