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 PREEMPT Сб 11 травня 20:31:08 CEST 2013 x86_64 GNU / Linux

rsync версія:

rsync 3.0.9-6

Відповіді:


13

Перша спроба (не спрацювала)

Додатково до файлів потрібно включити каталоги:

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) та show (S), які є альтернативним способом визначення стороною надсилання, включає / виключає.

  • Для позначення того, що правило застосовується до приймаючої сторони, використовується r . Якщо правило впливає на приймальну сторону, воно запобігає видаленню файлів. Для отримання додаткової інформації див. Модифікатор s. Дивіться також правила захисту (P) та ризику (R), які є альтернативним способом визначення на стороні приймача включає / виключає.

Дивіться людина 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, і це рік і місяць.

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 / target У цільовому каталозі будуть лише файли * .php та * .js.
lxtwin
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.