7

У меня есть 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 ответа2

11

Используйте 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"
)
2

Мне нравится ROBOCOPY. Использовал XCOPY в течение многих лет, а затем обнаружил необходимость в перезапускаемой операции копирования через медленное / раздражительное подключение к Интернету.

РОБОКОПИЯ src dest /s /e /xo

или зеркало

РОБОКОПИЯ src dest /mir

Используйте параметры ведения журнала, чтобы получить список для проверки позже.

ROBOCOPY src dest /s /e /xo /log:file

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