Фильтр Rsync: копирование одного шаблона только

Чтобы термофиксатор сообщил относительно PIDs о содержании монтирования, открытого, необходимо использовать-m

fuser -m /path
135
20.03.2011, 23:55
10 ответов

TL, DR:

rsync -am --include='*.pdf' --include='*/' --exclude='*' ~/LaTeX/ ~/Output/

Rsync копирует источник (источники) в место назначения. Если Вы передаете *.pdf как источники, оболочка разворачивает это до списка файлов с .pdf расширение в текущем каталоге. Никакого рекурсивного обхода не происходит, потому что Вы не передали каталога как источника.

Таким образом, необходимо работать rsync -a ~/LaTeX/ ~/Output/, но с фильтром, чтобы сказать rsync копировать .pdf файлы только. Правила фильтра Rsync могут казаться пугающими, когда Вы читаете руководство, но можно создать много примеров со всего несколькими простыми правилами.

  • Включения и исключения:

    • Исключая файлы по имени или местоположением легко: --exclude=*~, --exclude=/some/relative/location (относительно исходного аргумента, например, это исключает ~/LaTeX/some/relative/location).
    • Если Вы только хотите соответствовать нескольким файлам или местоположениям, включать их, включайте каждое продвижение каталога в них (например, с --include=*/), затем исключите остальных с --exclude='*'. Это вызвано тем, что:
    • При исключении каталога это исключает все ниже его. Исключенные файлы не рассмотрят вообще.
    • При включении каталога это автоматически не включает его содержание. В последних версиях, --include='directory/***' сделает это.
    • Для каждого файла первое правило соответствия применяется (и что-либо никогда подбираемое включено).
  • Шаблоны:

    • Если шаблон не содержит a /, это относится к имени файла без каталога.
    • Если шаблон заканчивается /, это относится к каталогам только.
    • Если шаблон запускается с /, это относится к целому пути от каталога, который был передан как аргумент rsync.
    • * любая подстрока единственного компонента каталога (т.е. никогда не соответствует /); ** соответствия любая подстрока пути.
  • Если исходный аргумент заканчивается a /, его содержание копируется (rsync -r a/ b создает b/foo для каждого a/foo). Иначе сам каталог копируется (rsync -r a b создает b/a).


Таким образом здесь мы должны включать *.pdf, включайте каталоги, содержащие их, и исключите все остальное.

rsync -a --include='*.pdf' --include='*/' --exclude='*' ~/LaTeX/ ~/Output/

Обратите внимание, что это копирует все каталоги, даже те, которые не содержат файла соответствия или подкаталога, содержащего один. Этого можно избежать с --prune-empty-dirs опция (это не универсальное решение, так как Вы затем не можете скопировать каталог даже путем соответствия ему явно, но это - редкое требование).

rsync -am --include='*.pdf' --include='*/' --exclude='*' ~/LaTeX/ ~/Output/
267
27.01.2020, 19:29
  • 1
    В отличие от моего решения (использующий zsh's ** шаблон), это воссоздает структуру каталогов в целевом dir. Я не уверен, является ли это тем, что OP хочет... –  Marcel Stimberg 29.09.2010, 15:08
rsync -av --include="*/" --include="*.pdf" --exclude="*" ~/Latex/ ~/Output/ --dry-run

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

Если Вы начинаетесь с:

--exclude '*' --include '*.pdf'

Затем жадное соответствие исключит все сразу же.

Если Вы пробуете:

--include '*.pdf' --exclude '*' 

Затем только файлы PDF в высокоуровневой папке будут переданы. Это не будет следовать никаким каталогам, так как они исключены '*'.

28
27.01.2020, 19:29
  • 1
    С 17.03.2014 это - лучший ответ, поскольку он решает исходный вопрос о плакатах точно. Проголосуйте за него! Если Вы добавляете --prune-empty-dirs (или ярлык -m) Вы даже экономите себя много пустых каталогов в месте назначения, кроме, конечно, Вас хотят их как напоминание или структурный проект. –  porg 18.03.2014, 01:38
  • 2
    Лучший ответ, - включают = "* /" является ключевым. –  Martin Konicek 05.08.2015, 14:46

Если Вы используете шаблон как *.pdf, оболочка “расширяется “, что шаблон, т.е. она заменяет шаблон всеми соответствиями в текущем каталоге. Команда, которую Вы выполняете (в этом случае rsync) не знает о том, что Вы пытались использовать шаблон.

При использовании zsh существует легкое решение, хотя: ** шаблон может использоваться для соответствия папкам рекурсивно. Попробуйте это:

rsync -avn ~/LaTeX/**/*.pdf ~/Output/
15
27.01.2020, 19:29
  • 1
    Разве это не скопировало бы весь pdfs с где-нибудь в текущем каталоге и всем от ~/LaTeX/к ~ / Вывод? –  SamB 16.09.2010, 21:35
  • 2
    я предполагаю Вас, означал rsync -avn ~/LaTeX/**/*.pdf ~/Output, но решение с --include более масштабируемо так или иначе. –  Adam Byrtek 16.09.2010, 21:58
  • 3
    Извините, исправил команду, которую я ввел с опечаткой в порыве... Я соглашаюсь, что включать команда (в версии SamB) лучше, хотя это немного более сложно и характерно для rsync в то время как ** мог бы стать удобным в других ситуациях также. –  Marcel Stimberg 16.09.2010, 22:10
  • 4
    Bash 4 принял ту же функцию. О, и Вам не нужен rsync здесь, CP сделает. В некоторых системах, если существует много файлов, это помогает сделать cd ~/Latex && cp -p **/*.pdf ~/Output избегать “командной строки слишком долго” ошибка. –  Gilles 'SO- stop being evil' 29.09.2010, 20:34
  • 5
    Обратите внимание, что шаблоны rsync, используемые во включении и, исключают фильтры, также имеют **, который делает то же самое. Можно выйти из * из других оболочек путем помещения их в кавычки. –  Dan Pritts 04.02.2015, 18:28

Можно использовать find и промежуточный список файлов (files_to_copy) решить Вашу проблему. Удостоверьтесь, что Вы находитесь в своем корневом каталоге, затем:

find LaTeX/ -type f -a -iname "*.pdf" > files_to_copy && rsync -avn --files-from=files_to_copy ~/ ~/Output/ && rm files_to_copy

Протестированный с Bash.

13
27.01.2020, 19:29
  • 1
    , я думаю, что находка является большей частью надежного решения, но я выбрал бы любое использование, находит -exec опция или использование xargs. Что-то как: find LaTeX/ -type f -iname "*.pdf" -print0 | xargs -0 -i rsync -avn {} Output/ –  Steven D 27.09.2010, 20:09
  • 2
    Да... Я предложил бы, находят также..., хотя я предполагаю, что rsync должен смочь сделать это. грязь –  gabe. 28.09.2010, 22:49
  • 3
    Это - аккуратное решение более трудной проблемы также: по-видимому, я мог использовать это для исключения файлов, класс документов которых standalone или которые не имеют a .tex файл с тем же именем, так как они будут изображениями, включенными в некоторый документ... –  Seamus 29.09.2010, 15:41
  • 4
    Мое разрешение 1280x1024, и я пытаюсь сделать (newmode) / добавляют (addmode) этот режим: "1280x1024_60.00" 108.88 1280 1360 1496 1712 1024 1025 1028 1060 -HSync +Vsync ---------121 опция--------47653----rsync --files-from принимает чтение из stdin. Это работало бы find LaTeX/ -type f -a -iname "*.pdf" | rsync -avn --files-from=- ~/ ~/Output/ –  Juan Calero 20.09.2012, 19:15

Судя разделом "INCLUDE/EXCLUDE PATTERN RULES" страницы справочника, способ сделать это

rsync -avn --include="*/" --include="*.pdf" ~/Latex/ ~/Output/

Критическое различие между ответом этого и kbrd --include="*/" флаг, который говорит rsync идти вперед и копировать любые каталоги, которые он находит, независимо от того, что их называют. Это необходимо, потому что rsync не рекурсивно вызовет в подкаталог, если он не был проинструктирован для копирования того подкаталога.

Кроме того, обратите внимание, что кавычки препятствуют тому, чтобы оболочка пыталась развернуть шаблоны до имен файлов относительно текущего каталога и выполнение одного из следующих действий:

  1. Успешно выполняясь и портя Ваш фильтр (не, слишком вероятно, посреди флага как этот, хотя Вы действительно никогда не знаете, когда кто-то сделает файл названным --include=foo.pdf ...)

  2. Сбой и потенциально создание ошибки вместо того, чтобы выполнить команду (поскольку Вы обнаружили zsh, делает по умолчанию).

9
27.01.2020, 19:29
  • 1
    Таким образом, это скопирует только PDFs и структуру каталогов, в то время как kbrd's скопирует файлы, но проигнорирует структуру? –  Seamus 17.09.2010, 12:29
  • 2
    Хм. Это на самом деле все еще, кажется, пытается скопировать все, я предполагаю, потому что это - то, что это обходится без фильтра, таким образом, includeлуг дополнительный материал уже там ничего не изменяет. Если Вы видите то, что я имею в виду... –  Seamus 17.09.2010, 12:33
  • 3
    Вам нужно --exclude="*" после --include="*.pdf", или это передаст все. –  jmanning2k 28.09.2010, 23:25
  • 4
    @jmanning2k: А-ч. Хороший для знания! –  SamB 30.09.2010, 00:18

Как насчет этого:

rsync -avn --include="*.pdf" ~/Latex/ ~/Output/
4
27.01.2020, 19:29
  • 1
    нет, man rsync помещает фильтр после опций и перед source/destiinations. Я попробовал это, и это не работало –  Seamus 16.09.2010, 19:06
  • 2
    Ваш путь находит файлы pdf в текущей папке, но не рекурсивно, как я хочу. ( a опция для архива, и среди прочего это делает копирование рекурсивным. человек –  Seamus 16.09.2010, 19:07
  • 3
    Ooops, мое плохое. Я обновил свой ответ. –  kbyrd 16.09.2010, 19:43
  • 4
    +1 для того, чтобы быть настолько близким, и дать мне ключ к разгадке то, как найти соответствующий материал в странице руководства. (Надо надеяться, я даже разобрался в нем. :-) –  SamB 16.09.2010, 22:04

Вот что-то, что должно работать без использования, находят. Различием от ответов, уже отправленных, является порядок правил фильтра. Правила фильтра в команде rsync работают много как iptable правила, первое правило, что файл соответствует, является тем, которое используется. Из страницы руководства:

Поскольку список файлов/каталогов для передачи создается, rsync проверяет, что каждое имя, которое будет передано против списка, включает/исключает шаблоны в свою очередь, и первый шаблон соответствия действуется на: если это - исключить шаблон, то тот файл пропускается; если это - включать шаблон затем, что имя файла не пропускается; если никакой шаблон соответствия не найден, то имя файла не пропускается.

Таким образом Вам нужна команда следующим образом:

rsync -avn --include="**.pdf" --exclude="*" ~/LaTeX/ ~/Output/

Отметьте шаблон "**.pdf". Согласно странице справочника:

если шаблон содержит / (не подсчет запаздывания/) или "**", то это подобрано против полного пути, включая любые ведущие каталоги. Если шаблон не содержит / или "**", то он подобран только против заключительного компонента имени файла. (Помните, что алгоритм применяется рекурсивно, таким образом, "полное имя файла" может на самом деле быть любой частью пути от начального каталога на вниз

В моем маленьком тесте это действительно работает рекурсивно вниз дерево каталогов и только выбирает pdfs.

3
27.01.2020, 19:29
  • 1
    Как точно Вы тестировали? Согласно моему пониманию документации и моей экспериментальной проверки, Ваша команда должна только скопировать *.pdf в каталоге верхнего уровня (но нет ~/LaTeX/foo/bar.pdf). –  Gilles 'SO- stop being evil' 28.09.2010, 22:25
  • 2
    @Gilles. Вы правы. Я поклялся, что протестировал это, и это работало, но я, может казаться, не воссоздаю его. И теперь, когда я на самом деле прочитал страницу справочника, которую я заключил в кавычки, она имеет смысл, что она не работает. Ворчание. –  Steven D 28.09.2010, 23:10
  • 3
    Ну, я выяснил, где мой тест был неправильным. Мой "маленький тест" был на каталоге, который имеет .tex и мои собственные файлы pdf. Я затем создал "тестовый" подкаталог и test.pdf и test.tex в этом subdir. Однако мне не удалось заметить, что был test.pdf в моем высокоуровневом dir, вероятно, из-за некоторых быстрый ЛАТЕКСНОГО эксперимента, который я сделал. –  Steven D 28.09.2010, 23:14
  • 4
    я все еще не понимаю **. Было бы хорошо иметь пример его. ;) –  buhtz 06.10.2017, 12:59

Это мое предпочтительное решение:

find source_dir -iname '*.jpg' -print0 |  rsync -0 -v --files-from=- . destination_dir/

Команда команда проще понять, чем включает / исключение правил rsync : -)

Если вы хотите скопировать Только файлы PDF, просто измените .jpg .pdf .pdf

2
27.01.2020, 19:29

Для создания каталога, содержащего только заголовки (.../include )из исходного каталога:

rsync -avh --prune-empty-dirs --exclude="build" --include="*/" --include="*.h" --exclude="*"./*../include/

Это исключает все пустые каталоги и каталогbuild

0
20.08.2021, 13:39

В обновлении ответа @Giles обратите внимание, что порядок команд включения и исключения должен быть изменен с текущими версиями (>=3.xx ), чтобы иметь параметры включения перед параметрами исключения в чтобы построить правильный список файлов. Я также считаю, что лучше всего сначала ставить инструкцию «включить все подкаталоги», а затем шаблон файла :

.
rsync -avh --include='*/' --include='file-pattern' --exclude='*' /sourcedir/ /targetdir/

т.е. в вашем случае:

rsync -avh --include='*/' -include='*.pdf' --exclude='*' ~/LaTeX/ ~/Output/

Дополнительные пояснения также можно найти в руководстве по адресуhttps://www.samba.org/ftp/rsync/rsync.htmlпод заголовком «ПРАВИЛА ФИЛЬТРАЦИИ» :

.

Note that, when using the --recursive (-r) option (which is implied by -a), every subdir component of every path is visited left to right, with each directory having a chance for exclusion before its content. In this way include/exclude patterns are applied recursively to the pathname of each node in the filesystem's tree (those inside the transfer). The exclude patterns short-circuit the directory traversal stage as rsync finds the files to send.

For instance, to include "/foo/bar/baz", the directories "/foo" and "/foo/bar" must not be excluded. Excluding one of those parent directories prevents the examination of its content, cutting off rsync's recursion into those paths and rendering the include for "/foo/bar/baz" ineffectual (since rsync can't match something it never sees in the cut-off section of the directory hierarchy).

The concept path exclusion is particularly important when using a trailing '*' rule. For instance, this won't work:

+ /some/path/this-file-will-not-be-found
+ /file-is-included
- *

This fails because the parent directory "some" is excluded by the '*' rule, so rsync never visits any of the files in the "some" or "some/path" directories. One solution is to ask for all directories in the hierarchy to be included by using a single rule: "+ */" (put it somewhere before the "- *" rule), and perhaps use the --prune-empty-dirs option. Another solution is to add specific include rules for all the parent dirs that need to be visited. For instance, this set of rules works fine:

+ /some/
+ /some/path/
+ /some/path/this-file-is-found
+ /file-also-included
- *

Here are some examples of exclude/include matching:

"- *.o" would exclude all names matching *.o
"- /foo" would exclude a file (or directory) named foo in the transfer-root directory
"- foo/" would exclude any directory named foo
"- /foo/*/bar" would exclude any file named bar which is at two levels below a directory named foo in the transfer-root directory
"- /foo/**/bar" would exclude any file named bar two or more levels below a directory named foo in the transfer-root directory
The combination of "+ */", "+ *.c", and "- *" would include all directories and C source files but nothing else (see also the --prune-empty-dirs option)
The combination of "+ foo/", "+ foo/bar.c", and "- *" would include only the foo directory and foo/bar.c (the foo directory must be explicitly included or it would be excluded by the "*")

The following modifiers are accepted after a "+" or "-":

A / specifies that the include/exclude rule should be matched against the absolute pathname of the current item. For example, "-/ /etc/passwd" would exclude the passwd file any time the transfer was sending files from the "/etc" directory, and "-⁠/ subdir/foo" would always exclude "foo" when it is in a dir named "subdir", even if "foo" is at the root of the current transfer.
A ! specifies that the include/exclude should take effect if the pattern fails to match. For instance, "-! */" would exclude all non-directories.
A C is used to indicate that all the global CVS-exclude rules should be inserted as excludes in place of the "-⁠C". No arg should follow.
An s is used to indicate that the rule applies to the sending side. When a rule affects the sending side, it prevents files from being transferred. The default is for a rule to affect both sides unless --delete-excluded was specified, in which case default rules become sender-side only. See also the hide (H) and show (S) rules, which are an alternate way to specify sending-side includes/excludes.
An r is used to indicate that the rule applies to the receiving side. When a rule affects the receiving side, it prevents files from being deleted. See the s modifier for more info. See also the protect (P) and risk (R) rules, which are an alternate way to specify receiver-side includes/excludes.
A p indicates that a rule is perishable, meaning that it is ignored in directories that are being deleted. For instance, the -C option's default rules that exclude things like "CVS" and "*.o" are marked as perishable, and will not prevent a directory that was removed on the source from being deleted on the destination.
An x indicates that a rule affects xattr names in xattr copy/delete operations (and is thus ignored when matching file/dir names). If no xattr-matching rules are specified, a default xattr filtering rule is used (see the --xattrs option).
1
20.08.2021, 13:39

Теги

Похожие вопросы