2

У меня есть каталог с тысячами файлов с именем number.jpg (например: 100152.jpg , 100153.jpg). Я не хочу копировать все в этом каталоге - только файлы с точным именем в качестве имен в списке текстовых файлов, который я создал.

В этом более коротком списке около 36 тыс. Имен - я хочу скопировать все файлы в большом каталоге, имена которых совпадают с именами в списке, в отдельную папку.

Как бы я мог сделать это, не переходя один за другим в систему Windows ?

2 ответа2

2

Вы можете использовать FOR /F и указывать полный путь к списку файлов, как показано ниже.

Это по существу будет читать каждую строку списка файлов, на который вы указываете, построчно, и итерировать возвращаемое значение (содержимое каждой строки) в команду XCOPY для соответствующей обработки.

Синтаксис командной строки

FOR /F "USEBACKQ TOKENS=*" %F IN ("C:\Folder\FileList.txt") DO XCOPY /F /Y "C:\SourceFolder\%~F" "C:\DestinationFolder\"

Синтаксис пакетного сценария

@ECHO ON

SET FileList=C:\Folder\FileList.txt
SET Source=C:\SourceFolder
SET Destination=C:\DestinationFolder

FOR /F "USEBACKQ TOKENS=*" %%F IN ("%FileList%") DO XCOPY /F /Y "%Source%\%%~F" "%Destination%\"

GOTO :EOF

Скрипт логика заметки

  • Опция USEBACKQ используемая в цикле FOR , гарантирует, что список файлов по-прежнему будет читаться, если в имени списка файлов или в его пути есть пробелы, и вам необходимо заключить в кавычки путь к списку файлов.

    • Например, SET FileList=C:\Folder Name\File List.txt
      • Без USEBACKQ цикл FOR в таком случае выдает ошибку
  • Опция TOKENS=* используемая в цикле FOR , гарантирует, что все значение будет возвращено при чтении из списка файлов, даже если в этом значении есть пробел

    • Например, список файлов имеет значение File 00 11.jpg поэтому значение имеет пробел в строке

      • Без TOKENS=* цикл FOR будет возвращать только часть значения этой строки перед первым пробелом, а не значение, как ожидалось (например, File)

Использование этих параметров, даже когда они не нужны, похоже, не приносит никакого вреда, и если вы когда-нибудь добавите такое значение или переменную в набор сценариев, он уже сможет соответственно обрабатывать такие случаи.


Дополнительные ресурсы

1

Я бы использовал bash любое время.

cat list.txt | xargs -I {} cp {} <destination folder>

Или, поскольку я предпочел parallel над xargs:

cat list.txt | parallel cp {} <destination folder>

В Windows я бы с Cygwin, но вы могли бы рассмотреть cmder, Git-для-Windows, , WsL и многое другое ...


Но вы можете сделать это почти так же легко в Powershell:

cat list.txt  | ForEach {cp $_ <destination folder>}

По-видимому, Microsoft хочет, чтобы определенная категория пользователей чувствовала себя комфортно, используя Powershell, потому что она распознает несколько известных команд из мира UNIX. Это всего лишь псевдонимы эквивалентных командлетов, и список можно найти, вызвав Get-Alias (или просто alias если вы предпочитаете):

cat -> Get-Content
clear -> Clear-Host
cp -> Copy-Item
curl -> Invoke-WebRequest
diff -> Compare-Object
echo -> Write-Output
history -> Get-History
kill -> Stop-Process
ls -> Get-ChildItem
man -> help
mount -> New-PSDrive
mv -> Move-Item
pwd -> Get-Location
rm -> Remove-Item
sleep -> Start-Sleep
wget -> Invoke-WebRequest

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .