rsync определенные файлы, исключая остальные, игнорируя каталог .svn /, рекурсивно


19

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

Рекурсивно мне нужно:

  • Удалить файлы в месте назначения, которые были удалены из источника
  • Только синхронизация .phpи .jsфайлы
  • Исключить все остальные типы файлов
  • Не удаляйте .svn/каталоги в месте назначения

Если я использую это:

rsync -zavC --delete --include='*.php' --include='*.js' --exclude="*" \
    /origin /destination

Тогда rsyncне является рекурсивным, потому что exclude="*"исключает все файлы, но и папки.

Если я добавлю, --include="*/"то .svn/каталог будет удален (он также будет включен).

Как я могу решить эту умопомрачительную дилемму?

uname -a:

Linux tux 3.9.2-1-ARCH # 1 ПРЕДСТАВЛЕНИЕ SMP Сб 11 мая 20:31:08 CEST 2013 x86_64 GNU / Linux

rsync версия:

rsync 3.0.9-6

Ответы:


13

1-я попытка (не сработала)

Вам необходимо включить каталоги в дополнение к файлам:

rsync -zavC --delete --include '*/' --include='*.php' --include='*.js' \
     --exclude="*" /media/datacod/Test/ /home/lucas/Desktop/rsync/

2-я попытка

rsync -avzC --filter='-rs_*/.svn*' --include="*/" --include='*.js' \
     --include='*.php' --exclude="*" --delete dir1/ dir2/

данные испытаний

Я написал этот скрипт, чтобы создать пример данных для проверки. Вот этот сценарий setup_svn_sample.bash:

#!/bin/bash

# setup .svn dirs
mkdir -p dir{1,2}/dir{1,2,3,4}/.svn

# fake data under .svn
mkdir -p dir1/dir{1,2,3,4}/.svn/origdir
mkdir -p dir2/dir{1,2,3,4}/.svn/keepdir

# files to not sync
touch dir1/dir{1,2,3,4}/file{1,2}

# files to sync
touch dir1/dir{1,2,3,4}/file1.js
touch dir1/dir{1,2,3,4}/file1.php

Запуск его производит следующие каталоги:

исходный каталог

$ tree -a dir1
dir1
|-- dir1
|   |-- file1
|   |-- file1.js
|   |-- file1.php
|   |-- file2
|   `-- .svn
|       `-- origdir
|-- dir2
|   |-- file1
|   |-- file1.js
|   |-- file1.php
|   |-- file2
|   `-- .svn
|       `-- origdir
|-- dir3
|   |-- file1
|   |-- file1.js
|   |-- file1.php
|   |-- file2
|   `-- .svn
|       `-- origdir
`-- dir4
    |-- file1
    |-- file1.js
    |-- file1.php
    |-- file2
    `-- .svn
        `-- origdir

пункт назначения

$ tree -a dir2
dir2
|-- dir1
|   `-- .svn
|       `-- keepdir
|-- dir2
|   `-- .svn
|       `-- keepdir
|-- dir3
|   `-- .svn
|       `-- keepdir
`-- dir4
    `-- .svn
        `-- keepdir

Выполнение вышеуказанной rsyncкоманды:

rsync -avzC --filter='-rs_*/.svn*' --include="*/" --include='*.js' \
     --include='*.php' --exclude="*" --delete dir1/ dir2/
sending incremental file list
dir1/file1.js
dir1/file1.php
dir2/file1.js
dir2/file1.php
dir3/file1.js
dir3/file1.php
dir4/file1.js
dir4/file1.php

sent 480 bytes  received 168 bytes  1296.00 bytes/sec
total size is 0  speedup is 0.00

В результате dir2 после этого:

$ tree -a dir2
dir2
|-- dir1
|   |-- file1.js
|   |-- file1.php
|   `-- .svn
|       `-- keepdir
|-- dir2
|   |-- file1.js
|   |-- file1.php
|   `-- .svn
|       `-- keepdir
|-- dir3
|   |-- file1.js
|   |-- file1.php
|   `-- .svn
|       `-- keepdir
`-- dir4
    |-- file1.js
    |-- file1.php
    `-- .svn
        `-- keepdir

Почему это работает?

Ключевым элементом этого скрипта является использование возможности фильтров rsync. Фильтры позволяют удалять файлы из соответствующего набора в различных точках команды. Так что в нашем случае мы фильтруем любые файлы, которые соответствуют шаблону */.svn*. Модификаторы -rs_сообщают фильтру, что мы хотим фильтровать как на стороне источника, так и на стороне цели.

выдержка из раздела «ЗАМЕЧАНИЯ ФИЛЬТРА» на справочной странице rsync

  • S используется для указания того, что правило применяется к передающей стороне. Когда правило влияет на отправляющую сторону, оно предотвращает передачу файлов. По умолчанию правило влияет на обе стороны, если --delete-excludedне указано иное, в этом случае правила по умолчанию становятся только на стороне отправителя. См. Также правила скрытия (H) и показа (S), которые являются альтернативным способом указания включений / исключений на стороне отправителя.

  • Г используется для указания того, что правило применяется к принимающей стороне. Когда правило влияет на принимающую сторону, оно предотвращает удаление файлов. Смотрите модификатор s для получения дополнительной информации. См. Также правила защиты (P) и риска (R), которые являются альтернативным способом указания включений / исключений на стороне получателя.

Смотрите man rsync для более подробной информации.

Советы по выяснению этого (подсказка --dry-run)

Описывая, как это сделать, я подумал, что упомяну --dry-runпереключатель rsync. Чрезвычайно полезно видеть, что произойдет, не имея rsyncфактического события .

Например

Использование следующей команды выполнит тестовый прогон и покажет нам логику принятия решения rsync:

rsync --dry-run -avvzC --filter='-rs_*/.svn*' --include="*/" \
     --include='*.js' --include='*.php' --exclude="*" --delete dir1/ dir2/
sending incremental file list
[sender] showing directory dir3 because of pattern */
[sender] showing directory dir2 because of pattern */
[sender] showing directory dir4 because of pattern */
[sender] showing directory dir1 because of pattern */
[sender] hiding file dir1/file1 because of pattern *
[sender] showing file dir1/file1.js because of pattern *.js
[sender] hiding file dir1/file2 because of pattern *
[sender] showing file dir1/file1.php because of pattern *.php
[sender] hiding directory dir1/.svn because of pattern */.svn*
[sender] hiding file dir2/file1 because of pattern *
[sender] showing file dir2/file1.js because of pattern *.js
[sender] hiding file dir2/file2 because of pattern *
[sender] showing file dir2/file1.php because of pattern *.php
[sender] hiding directory dir2/.svn because of pattern */.svn*
[sender] hiding file dir3/file1 because of pattern *
[sender] showing file dir3/file1.js because of pattern *.js
[sender] hiding file dir3/file2 because of pattern *
[sender] showing file dir3/file1.php because of pattern *.php
[sender] hiding directory dir3/.svn because of pattern */.svn*
[sender] hiding file dir4/file1 because of pattern *
[sender] showing file dir4/file1.js because of pattern *.js
[sender] hiding file dir4/file2 because of pattern *
[sender] showing file dir4/file1.php because of pattern *.php
[sender] hiding directory dir4/.svn because of pattern */.svn*
delta-transmission disabled for local transfer or --whole-file
[generator] risking directory dir3 because of pattern */
[generator] risking directory dir2 because of pattern */
[generator] risking directory dir4 because of pattern */
[generator] risking directory dir1 because of pattern */
[generator] protecting directory dir1/.svn because of pattern */.svn*
dir1/file1.js
dir1/file1.php
[generator] protecting directory dir2/.svn because of pattern */.svn*
dir2/file1.js
dir2/file1.php
[generator] protecting directory dir3/.svn because of pattern */.svn*
dir3/file1.js
dir3/file1.php
[generator] protecting directory dir4/.svn because of pattern */.svn*
dir4/file1.js
dir4/file1.php
total: matches=0  hash_hits=0  false_alarms=0 data=0

sent 231 bytes  received 55 bytes  572.00 bytes/sec
total size is 0  speedup is 0.00 (DRY RUN)

В приведенном выше выводе вы можете видеть, что ./svnкаталоги защищены нашим правилом фильтрации. Ценная информация для отладки rsync.

Ссылки


Уже попробовал это, как я уже говорил выше. Если я это сделаю, то каталог .SVN также будет включен (скорее всего, удален, поскольку он не существует в источнике или не изменен). Очень важно оставить каталог .SVN без изменений. В любом случае, спасибо за попытку! :)
canolucas

-C должен игнорировать ".SVN /", но include="*/"включает его
canolucas

Вы правы. Должно быть .svn, редактирование ответа. Во всяком случае, после переименования проблема остается. -Cи include="*/", кажется, не очень близкие друзья :(
canolucas

10

Хорошо, после нескольких попыток я разобрался с этим:

rsync -vaiz --delete --exclude=.svn/ --include='*.php' --include='*.js' \
    --include='*/' --exclude='*' --prune-empty-dirs \
    --filter "protect .svn/" /origin /destination

Спасибо


Отличный ответ. Мой фильтр защищает .svn/каталоги --prune-empty-dirsв том случае, если они пусты. Другой подход, это дублирование пустых rsync -vaiz --delete --exclude=.svn/ --include='*.php' --include='*.js' --include='*/' --exclude='*' /origin /destination
папок

Ключ моего подхода состоит в том, чтобы --exclude=.svn/до того , как --include«S
canolucas

Хороший ответ. Я бы предложил исключить = '. Svn /', но я думал, что вы хотите использовать -C. Рад, что вы поняли это!
SLM

0

Хотя это не использует rsync, другой вариант - использовать find и cpio. Например, у меня есть каталог под названием «Фото» и это год и месяц.

Photos
├── 2002
   ├── 2002-03
      ├── 2002-03-30
      ├── 2002-03-31
      └── 2002-03-31-02
   ├── 2002-04
      ├── 2002-04-01
      ├── 2002-04-01-03
      ├── 2002-04-07
      ├── 2002-04-21
      ├── 2002-04-22
      ├── 2002-04-22-02
      └── 2002-04-27
   ├── 2002-05
      ├── 2002-05-02
      ├── 2002-05-03

Но здесь у меня есть JPG, DNG, XML и другие вещи, и я хочу только JPG, поэтому я бы сделал это

"cd" в каталог над каталогом Photos затем:

find Photos -type f -name "*jpg" -print | cpio -pdmvu /fast

И пошло-поехало

/fast/Photos/2002/2002-04/2002-04-22/bath problem.jpg
/fast/Photos/2002/2002-04/2002-04-22-02/full bath.jpg
/fast/Photos/2002/2002-07/2002-07-10/Broken Top.jpg
/fast/Photos/2002/2002-12/2002-12-28/101-0125_IM~~G.jpg
/fast/Photos/2002/2002-12/2002-12-28/small-101-0125_IM~~G.jpg
/fast/Photos/2003/2003-01/2003-01-19/k1.jpg
/fast/Photos/2003/2003-01/2003-01-19/k2.jpg
/fast/Photos/2003/2003-02/2003-02-23/quinn.jpg
/fast/Photos/2003/2003-05/2003-05-04/all.jpg
/fast/Photos/2003/2003-05/2003-05-09/100_0015_r1.jpg
/fast/Photos/2003/2003-05/2003-05-09/100_0006_2_r1.jpg
/fast/Photos/2003/2003-05/2003-05-09/100_0006_r1.jpg
/fast/Photos/2003/2003-05/2003-05-09/100_0007_2_r1.jpg

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


Это не отвечает на вопрос.
Ральф Фридл

Если он использует: find / origin -type f (-name " .php" -o -name " .js") -print | cpio -pdmvu / destination В целевом каталоге будут находиться только файлы * .php и * .js.
LXTWIN
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.