Копирование только новых файлов из одной папки в другую
У меня есть 2 папки с файлами. Эти файлы являются продуктом некоторого процесса сборки. Первая папка - это выходные данные предыдущей сборки, а вторая - выходные данные текущей сборки.
Я хотел бы как-то различать эти 2 папки из командной строки / сценария сборки и копировать только файлы, которые были добавлены, или файлы, которые являются новыми, в какую-то другую папку.
Например:
**FOLDER1** (new build)
a.txt
b.txt (modified)
c.txt
d.txt
**FOLDER2** (prev build)
a.txt
b.txt
c.txt
Исходя из этого, интересующая меня операция копирования будет копировать только b.txt и d.txt в другую папку (не в folder2).
По сути, я только после "дельт", и я хотел бы хранить их в каком-то месте.
Возможно ли это с помощью стандартных инструментов командной строки, которые поставляются с Windows? (предположим, Windows 7/Server 2008 или выше)
2 ответа
Используйте XCOPY с параметрами /D и /L, "копируя" из папки 1 в папку 2.
Параметр /D ограничивает копирование только новыми или измененными файлами.
Параметр /L заставляет команду перечислить файлы, которые будут скопированы, но предотвращает фактическое создание копий.
Затем используйте FOR /F для обработки этих результатов и фактически скопируйте файлы в папку 3.
for /f "eol=: delims=" %F in ('xcopy /dl "folder1\*" "folder2"') do @copy "%F" "f3" >nul
Если положить в командный файл, то все %
должен быть удвоен как %%
,
XCOPY также выводит сводную информацию о том, сколько файлов затронуты (будут затронуты). Выше будет попытаться скопировать файл с итоговым счетчиком "имя", и, конечно, не удастся. Перенаправление вывода на nul предотвращает отображение сообщения об ошибке. Я проверил на Windows 7 и был удивлен, сообщение об ошибке было на stdout, а не stderr. Если сообщение об ошибке в других версиях появляется на stderr, команда также должна получить 2>nul, чтобы предотвратить сообщение об ошибке.
Но есть риск скрыть сообщения об ошибках - что делать, если по какой-то причине происходит сбой копирования?
Вот скрипт, который перечислит все файлы, которые были успешно скопированы, а также укажет, какие (если таковые имеются) не удалось. Он использует FINDSTR, чтобы отфильтровать количество ненужных файлов. Предполагается, что количество файлов на английском языке, с формой NNN File(s)
, поэтому он должен быть изменен для других языков.
@echo off
for /f "eol=: delims=" %%F in (
'xcopy /dl "folder1\*" "folder2" ^| findstr /v "^[0-9][0-9]* File(s)"'
) do copy "%%F" "folder3" >nul && echo "%%F"|| echo FAILED: "%%f"
Вот более сложный вариант, который работает с любым языком. Он сохраняет каждое имя файла в переменной и задерживает копирование до следующей итерации цикла. Последняя запись (количество) никогда не копируется.
@echo off
setlocal disableDelayedExpansion
set "file="
for /f "eol=: delims=" %%F in ('xcopy /dl "folder1\*" "folder2"') do (
if defined file (
setlocal enableDelayedExpansion
copy "!file!" "folder3" >nul && echo "!file!" || echo FAILED: "!file!"
endlocal
)
set "file=%%F"
)
Мне нравится ROBOCOPY вместо этого. Использовал XCOPY в течение многих лет, а затем обнаружил необходимость в перезапускаемой операции копирования через медленное / раздражительное подключение к Интернету.
РОБОКОПИЯ src dest /s /e /xo
или зеркало
РОБОКОПИЯ src dest / mir
Используйте параметры ведения журнала, чтобы получить список для проверки позже.
ROBOCOPY src dest /s /e /xo / log: file