Использование параметров включения и исключения Rsync для включения каталога и файла по шаблону

У меня проблемы с правильным синтаксисом rsync, и мне интересно, действительно ли мой сценарий может быть обработан с помощью rsync. Во-первых, я подтвердил, что rsync прекрасно работает между моим локальным хостом и моим удаленным хостом. Выполнение прямой синхронизации с каталогом прошло успешно.

Вот как выглядит моя файловая система:

uploads/
  1260000000/
    file_11_00.jpg
    file_11_01.jpg
    file_12_00.jpg
  1270000000/
    file_11_00.jpg
    file_11_01.jpg
    file_12_00.jpg
  1280000000/
    file_11_00.jpg
    file_11_01.jpg
    file_12_00.jpg

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

Вот команда, которую я пытаюсь:

rsync -nrv --include="**/file_11*.jpg" --exclude="*" /Storage/uploads/ /website/uploads/

Это приводит к тому, что в моем пробном прогоне 0 файлов помечаются для передачи. Я пробовал различные другие комбинации операторов --include и --exclude, но либо по-прежнему не получал результатов, либо получал все, как если бы не были установлены параметры включения или исключения.

Кто-нибудь знает, как это сделать?


person Sheldon Chang    schedule 31.03.2012    source источник


Ответы (4)


Проблема в том, что --exclude="*" говорит об исключении (например) каталога 1260000000/, поэтому rsync никогда не проверяет содержимое этого каталога, поэтому никогда не замечает, что каталог содержит файлы, которые были бы сопоставлены вашим --include.

Я думаю, что самое близкое к тому, что вы хотите, это следующее:

rsync -nrv --include="*/" --include="file_11*.jpg" --exclude="*" /Storage/uploads/ /website/uploads/

(который будет включать все каталоги и все файлы, соответствующие file_11*.jpg, но не другие файлы), или возможно это:

rsync -nrv --include="/[0-9][0-9][0-9]0000000/" --include="file_11*.jpg" --exclude="*" /Storage/uploads/ /website/uploads/

(та же концепция, но гораздо более требовательна к каталогам, которые она будет включать).

person ruakh    schedule 31.03.2012
comment
Спасибо! Это было именно то, что мне было нужно. Мой сценарий на самом деле был более или менее тем, что вы описали во втором примере, но я оставил свой вопрос упрощенным, чтобы сделать вопрос более прямым. - person Sheldon Chang; 01.04.2012
comment
Обратите внимание на важность (например) --include="*/" для включения родительских каталогов файлов, которые вы действительно хотите включить. - person mabraham; 06.01.2016
comment
Обратите внимание на порядок аргументов: --include должен стоять перед --exclude - person hfs; 04.04.2016
comment
@hfs Да, я считаю, что об этом следует упомянуть в собственном ответе. Я пытался сделать что-то подобное, прежде чем нашел эту страницу, и знал, что мне нужен -include="*/", но это все равно не сработало. Глядя на этот ответ, я первой подумал, что именно это я и делаю! Потом я заметил, что порядок был другим. - person Laurence Gonsalves; 07.12.2017
comment
Другая ключевая концепция заключается в том, что при использовании параметра --recursive (-r) (который подразумевается -a) каждый субкомпонент каждого пути посещается сверху вниз, поэтому шаблоны включения / исключения рекурсивно применяются к полному имени каждого субкомпонента. - person wisbucky; 24.11.2020

rsync включить примеры шаблонов исключения:

"*"         means everything
"dir1"      transfers empty directory [dir1]
"dir*"      transfers empty directories like: "dir1", "dir2", "dir3", etc...
"file*"     transfers files whose names start with [file]
"dir**"     transfers every path that starts with [dir] like "dir1/file.txt", "dir2/bar/ffaa.html", etc...
"dir***"    same as above
"dir1/*"    does nothing
"dir1/**"   does nothing
"dir1/***"  transfers [dir1] directory and all its contents like "dir1/file.txt", "dir1/fooo.sh", "dir1/fold/baar.py", etc...

И последнее замечание: просто не полагайтесь на звездочки, которые используются в начале для оценки путей; например "**dir" (их можно использовать для отдельных папок или файлов, но не для путей) и обратите внимание, что более двух звездочек не работают для имен файлов.

person AmirHossein    schedule 28.12.2017
comment
Ваш ответ - единственный, который можно использовать, потому что вы объясняете общее поведение. Другие ответы слишком конкретны в соответствии с OP, но для каждой ситуации требуется другое решение! Это мне очень помогло! - person Peter VARGA; 04.02.2018
comment
@AlBundy Я рада! - person AmirHossein; 04.02.2018
comment
Подробное, но не такое интуитивное объяснение можно найти на rsync странице руководства в разделе INCLUDE/EXCLUDE PATTERN RULES - person Griddo; 02.08.2019

Добавьте -m к рекомендованному ответу выше, чтобы удалить пустые каталоги.

person brandon    schedule 25.01.2017

Вот мой ответ научить человека ловить рыбу:

Синтаксис Rsync определенно не интуитивно понятен, но его стоит понять.

  1. Сначала используйте -vvv, чтобы увидеть отладочную информацию для rsync.
$ rsync -nr -vvv --include="**/file_11*.jpg" --exclude="*" /Storage/uploads/ /website/uploads/

[sender] hiding directory 1280000000 because of pattern *
[sender] hiding directory 1260000000 because of pattern *
[sender] hiding directory 1270000000 because of pattern *

Ключевой концепцией здесь является то, что rsync рекурсивно применяет шаблоны включения / исключения для каждого каталога. Как только будет найдено совпадение с первым включением / исключением, обработка останавливается.

Первый оцениваемый каталог - /Storage/uploads. Storage/uploads имеет 1280000000/, 1260000000/, 1270000000/ каталогов / файлов. Ни один из них не соответствует file_11*.jpg для включения. Все они соответствуют * для исключения. Итак, они исключаются, и rsync завершается.

  1. Решение состоит в том, чтобы сначала включить все каталоги (*/). Тогда первым компонентом dir будет 1260000000/, 1270000000/, 1280000000/, поскольку они соответствуют */. Следующим компонентом каталога будет 1260000000/. В 1260000000/ file_11_00.jpg соответствует --include="file_11*.jpg", поэтому он включен. И так далее.
$ rsync -nrv --include='*/' --include="file_11*.jpg" --exclude="*" /Storage/uploads/ /website/uploads/

./
1260000000/
1260000000/file_11_00.jpg
1260000000/file_11_01.jpg
1270000000/
1270000000/file_11_00.jpg
1270000000/file_11_01.jpg
1280000000/
1280000000/file_11_00.jpg
1280000000/file_11_01.jpg

https://download.samba.org/pub/rsync/rsync.1

person wisbucky    schedule 24.11.2020