Rsync: рекурсивно синхронизировать все файлы, игнорируя структуру каталогов
Я пытаюсь создать bash script для синхронизации музыки с моего рабочего стола с мобильным устройством. Рабочий стол - это источник.
Есть ли способ сделать rsync рекурсивно синхронизировать файлы, но игнорировать структуру каталогов? Если файл был удален с рабочего стола, я хочу, чтобы его также удаляли на устройстве.
Структура каталогов на моем рабочем столе примерно такая.
Artist1/
Artist1/art1_track1.mp3
Artist1/art1_track2.mp3
Artist1/art1_track3.mp3
Artist2/
Artist2/art2_track1.mp3
Artist2/art2_track2.mp3
Artist2/art2_track3.mp3
...
Структура каталога, которую я хочу на устройстве:
Music/
art1_track1.mp3
art1_track2.mp3
art1_track3.mp3
art2_track1.mp3
art2_track2.mp3
art2_track3.mp3
...
Ответы
Ответ 1
Просто:
rsync -a --delete --include=*.mp3 --exclude=* \
pathToSongs/Theme*/Artist*/. [email protected]:Music/.
выполнит задание, если у вас иерархия путей имеет фиксированное количество уровней.
ПРЕДУПРЕЖДЕНИЕ: если два файла песни имеют точно такое же имя, в то же время в одном каталоге назначения ваша резервная копия пропустит один из них!
Если else и для строгого ответа на ваш запрос, игнорируя структуру каталогов, вы можете использовать bash shopt -s globstar
:
shopt -s globstar
rsync -a --delete --include=*.mp3 --exclude=* \
pathToSongsRoot/**/. [email protected]:Music/.
В любом случае нет необходимости форкировать команду find
.
Рекурсивно синхронизировать все файлы при игнорировании структуры каталогов
Для строгого ответа на вопрос не следует ограничиваться расширением:
shopt -s globstar
rsync -d --delete sourceRoot/**/. [email protected]:destRoot/.
При этом будут скопированы каталоги, но без содержимого. Все каталоги и будут храниться на одном уровне с destRoot/
.
ПРЕДУПРЕЖДЕНИЕ. Если в каталогах дефферентов существуют несколько разных файлов с одинаковым именем, они просто будут перезаписаны по назначению, durring rsync, для окончательного хранения случайным образом только одного.
Ответ 2
Возможно, это недавний вариант, но я вижу вариант --no-relative
, упомянутый в документации для --files-from
, и он отлично работал.
find SourceDir -name \*.mp3 | rsync -av --files-from - --no-relative . DestinationDir/
Ответ 3
Ответ на ваш вопрос: Нет, rsync
не может сделать это в одиночку. Но с помощью других инструментов мы можем добраться туда... После нескольких попыток я придумал следующее:
rsync -d --delete $(find . -type d|while read d ; do echo $d/ ; done) /targetDirectory && rmdir /targetDirectory/* 2>&-
Трудность заключается в следующем: чтобы включить удаление файлов в целевой позиции, вам необходимо:
- укажите каталоги в качестве источников для rsync (он не удаляет, если источником является список файлов).
- предоставить ему полный список источников сразу (
rsync
в цикле даст вам содержимое последнего каталога только в целевом объекте).
- завершите имена каталогов косой чертой (в противном случае они создадут каталоги в целевом каталоге)
Таким образом, подстановка команд (материал, заключенный в $(
)
), делает следующее: он находит все каталоги и добавляет косую черту (/) в конце имен каталогов. Теперь rsync видит список исходных каталогов, все заканчиваются косой чертой и, таким образом, копируют их содержимое в целевой каталог. Опция -d
сообщает об этом, а не копирует рекурсивно.
Второй трюк - это rmdir /targetDirectory/*
, который удаляет пустые каталоги, созданные rsync
(хотя мы этого не просили).
Я протестировал это, и удаление файлов, удаленных в исходном дереве, работало нормально.
Ответ 4
Если вы можете составить список файлов, вы уже решили проблему.
Попробуйте:
find /path/to/src/ -name \*.mp3 > list.txt
rsync -avi --no-relative --progress --files-from=list.txt / [email protected]:/path/to/dest
Если вы снова запустите script для новых файлов, он будет копировать только отсутствующие файлы.
Если вам не нравится этот список, попробуйте выполнить одно предложение (но это другая логика)
find /path/to/src/ -name \*.mp3 -type f \
-exec rsync -avi --progress {} [email protected]:/path/to/dest/ \;
В этом случае вы будете запрашивать каждый файл каждый раз, поскольку по типу предложения вы не можете предварительно создать список файлов.