2

У меня есть две директории с тысячами файлов, которые содержат более или менее одинаковые файлы.

Как я могу скопировать все файлы из dirA в dirB, которые не находятся в dirB, или если файл существует в dirB, только перезаписать его, если он меньше.

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

Предыстория моей проблемы:
Я выполнил рендеринг dynmap на своем сервере Minecraft, но некоторые плитки отсутствуют или повреждены. Затем я снова выполнил рендеринг на другом компьютере с более быстрым ЦП и скопировал все новые отрендеренные файлы (файлы PNG ~ 50 ГБ / 6.000.000 ~ 4-10 КБ) на мой сервер. После этого я заметил, что в моем новом рендере также есть поврежденные файлы.

слева: старый рендер, справа: новый рендер

старый 1 поврежден новый 1

старый 2 новый 2 поврежден

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

3 ответа3

2

Может быть, грязный путь, но я надеюсь, что это то, что вы ищете

#!/bin/bash

### Purpose:
# Copy huge amount of files from source to destination directory only if
# destination file is smaller in size than in source directory
###

src='./d1' # Source directory
dst='./d2' # Destination directory

icp() {
  f="${1}";
  [ -d "$f" ] && {
    [ ! -d "${dst}${f#$src}" ] && mkdir -p "${dst}${f#$src}";
    return
  }

  [ ! -f "${dst}/${f#$src/}" ] && { cp -a "${f}" "${dst}/${f#$src/}"; return; }
  fsizeSrc=$( stat -c %s "$f" )
  fsizeDst=$( stat -c %s "${dst}/${f#$src/}" )
  [ ${fsizeDst} -lt ${fsizeSrc} ] && cp -a "${f}" "${dst}/${f#$src/}"
}

export -f icp
export src
export dst

find ${src} -exec bash -c 'icp "$0"' {} \;
1

Вы можете использовать команду rsync

Синтаксис:

-a = archive mode
-v = increase verbosity
-z = compress file data during the transfer
--progress = show progress during transfer

rsync -avz --progress <source path> <destination path>

Вы можете использовать --delete для удаления посторонних файлов из директории назначения

rsync -avz --delete --progress <source path> <destination path>

поэтому ваша команда будет:

rsync -avz --delete --progress dirA dirB
0

Моя проблема была похожа. Я хотел синхронизировать файлы из удаленной папки в локальную, но копировать только те удаленные файлы, которые были больше, чем соответствующие локальные файлы.

Мой обходной путь с rsync был таким, который на самом деле был однострочным:

for x in $(ls -1 home/me/local/folder/*)
do
    eachsize=$(stat -c "%s")
    rsync -avz --progress --max-size=${eachsize} remote:/home/you/folder/${x} .
done

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

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