Перемещать файлы и удалять каталоги с помощью rsync?


17

Недавно мне нужно было удалить большое количество файлов (более 1 миллиона), и я прочитал, что делает:

rsync -av --delete `mktemp -d`/ ~/source && rmdir ~/source

Был один из самых оптимизированных способов сделать это, и я могу поручиться, что это быстрее, чем rm -rf.

Я не эксперт в этом вопросе, но из моего понимания причина производительности rsync связана с тем, как она выводит список файлов (я полагаю, LIFO вместо FIFO). Теперь проблема в том, что мне также нужно эффективно перемещать большое количество файлов. Немного поиска, я нашел это:

rsync -av --ignore-existing --remove-source-files ~/source ~/destination

Хотя это удаляет все переместились файлы в ~/sourceэтих каталогах остаются там. Поскольку у меня есть структура каталогов, похожая на «циклический перебор», число files/directoriesочень близко к 1, поэтому я вынужден снова выполнить первую команду, чтобы полностью избавиться от каталога:

rsync -av --ignore-existing --remove-source-files ~/source ~/destination && \
rsync -av --delete `mktemp -d`/ ~/source && rmdir ~/source

Стрит mvзакончится практически мгновенно, но в моем ~/destinationкаталоге есть файлы, которые следует хранить, поэтому mvэто не вариант. Я нашел параметры --prune-empty-dirsи --forcersync, но ни один из них не работает так, как я ожидал:

--force                 force deletion of directories even if not empty
--prune-empty-dirs      prune empty directory chains from the file-list
--remove-source-files   sender removes synchronized files (non-dirs)

Есть ли способ имитировать движение с rsync за один раз?


2
Если вы не получили ответа, попробуйте опубликовать в списке rsync. Они очень полезны. lists.samba.org/mailman/listinfo/rsync
Джо

Ответы:


7

Я нашел эту тему в stackoverflow под названием: Удаление папок с помощью rsync «move»? , который задает по существу тот же вопрос. В одном из ответов предлагалось выполнить команды rsyncin 2, поскольку оказалось, что нет ни одной команды, которая могла бы выполнить перемещение / удаление файлов и исходных каталогов.

$ rsync -av --ignore-existing --remove-source-files source/ destination/ && \
  rsync -av --delete `mktemp -d`/ source/ && rmdir source/

В качестве альтернативы вы можете сделать это с помощью этой команды:

$ rsync -axvvES --remove-source-files source_directory /destination/ && \
  rm -rf source_directory

Не идеально, но делает работу.


Да, именно я ответил на этот вопрос (и то же самое «решение» также на этот вопрос). = P
Аликс Аксель

@AlixAxel - Ха, прости, я даже не заметил, что ты ответил на этот вопрос. Ну что ж. Должен ли я удалить этот ответ тогда?
SLM

3
Использование rsyncдля удаления каталогов не является правильным, и всегда есть опасность rm -rf. Я бы порекомендовал 2-й шаг:find source/ -d -type d -exec rmdir {} \;
zany

2
Я просто чувствую себя обязанным добавлять, никогда не использовать -deleteи --remove-source-filesв одной команде rsync (приведенные выше примеры хороши, это тангенциально). Если вы прервете, а затем повторите то, что я описываю, вы потеряете переданные файлы. Что я делал раньше :(
Шридхар Сарнобат

Когда я прибираюсь с этим find, я предпочитаю следующее: find source/ -type d -empty -delete это дает мне странное чувство уверенности в том, что это не будет просто затирать все.
Greyfade

10

От комментария Зани до ответа СЛМ ( Перемещение файлов и удаление каталогов с помощью rsync? ) Я бы порекомендовал эти 2 команды в качестве ответа:

rsync -av --ignore-existing --remove-source-files source/ destination/ && \
find source/ -depth -type d  -empty -exec rmdir "{}" \;

Преимущество в том, что, как сказал Зани, использование rm -rf все еще сопряжено с некоторой опасностью, если вы не понимаете это правильно или для новичков.

Я добавил 2 параметра, -depth и -empty, и хотя я не уверен, действительно ли это необходимо, вторая команда становится более переносимой для других ситуаций и даже более безопасной (она по-прежнему работает правильно, если некоторые каталоги не пусты и начинает удаление из самой глубокой точки в дереве каталогов)


почему не просто -deleteвместо -exec rmdir {} \;?
летающая овца

@flying_sheep см. комментарий пользователя user7000 в ответе сима: когда прерывается rsync, вы можете потерять файлы
с

Когда rsync прерывается, поиск никогда не начинается или нет? Так что -delete во втором rsync не должно быть проблемой. Но -delete также удаляет файлы, вместо rmdir никогда не удаляет файлы, только каталоги. Оба (-delete и rmdir) проверяют каталоги, если они пусты перед удалением.
Бенба

Кроме того, на страницах руководства написано, что вы должны использовать -execdir вместо -exec ...
benba

2

Это делает работу за один шаг. Обратите внимание на трейлинг / косую черту / на пути источника и цели.

rsync \
    -ruval \
    --ignore-existing \
    --remove-source-files \
    --prune-empty-dirs \ 
    /source/path/ /target/path/

Я повторяю предупреждение от user7000 не использовать --deleteи --remove-source-filesвместе в одном вызове rsync. Если операция завершится неудачно или прервется, и тот же вызов будет повторен, вы потеряете данные. В случае каких-либо сомнений используйте --dry-runопцию, чтобы увидеть, что будет сделано.


-ruvalкажется излишним. -aэквивалентно -rlptgoD, который включает в себя как -rи -l.
Greyfade
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.