Intereting Posts
как добавить второй адрес ipv6 в Linux, не делая его по умолчанию Невозможно взаимодействовать или переключать tty, но SysRQ + O и SysRQ + B работают. Что это за статус? Как использовать октаву для нахождения численных решений для системы нелинейных уравнений? Как извлечь текст с помощью sed Redis как сервис для CentOs6 Программный рейд + отдельные разделы? проблема с установкой fedora 19 Самый простой способ использовать содержимое каталога? Почему передача HEREDOC в виде строки для `ruby -e` не работает? Список версий программного обеспечения по умолчанию для данного выпуска Ubuntu скопировать содержимое переменной в текстовый файл Сделать OpenGL GLX работать с клиентом Steam на Debian jessie назначить количество выходных строк переменной Как найти процессы с помощью последовательного порта Почему postfix не проверяет отправителя, кто, как они говорят, использует обратные dns, SPF или DMARC?

Рекурсивно копировать только определенные каталоги, которые соответствуют шаблонам, перечисленным в файле

У меня есть каталог со следующей структурой:

-- 201893208 └── 8Z12 └── ko_8Z12_Full └── wp_we_8Z12_FullDAT └── 8Z12_DATFull └── P011 └── P011_Full └── 8Z12_FullDAT └── P011_DATFull └── 9FZA └── kl_wt-we-w_kl9-9FZA_Full └── ffd-9FZA_FullDAT └── 8fdZ12232_9FZA_DATFull -- 903240920 └── P0fsa └── P0fsa_Full └── P0fsa_FullDAT └── P0fsa_DATFull └── Paaaf └── we-Paaaf_ww_fl_Full └── Paaaf_FullDAT └── Paaaf_DATFull └── 9FZATYYY └── 9FZATYYY_Full └── 9FZATYYY_FullDAT -- wt0340291 └── OPF1121 └── OPF1121_Full └── 8Z12_DATFull └── KLOFJ9 └── lop_KLOFJ9_ffj_Full └── powt_KLOFJ9_DATFull └── LP02323 └── wr_we_LP02323_Full └── wr_we_LP02323_FullDAT 

Есть тысячи файлов в каждой папке, перечисленной выше. И затем есть также много подкаталогов внутри каждого. Например, 8Z12 не содержит только три папки, перечисленные выше, но также содержит тысячи файлов.

Я ТОЛЬКО хочу скопировать каталоги, у которых _Full в конце их имени ( каталоги DATFull НЕ должны копироваться ), а также содержат шаблоны в списке ниже

 LP02323 KLOFJ9 Paaaf 9FZA 

Другими словами, каталоги, которые содержат строку из списка выше AND Full в своем имени (но НЕ DAT), должны быть скопированы.

Поэтому в приведенном выше примере должны быть скопированы только следующие каталоги (и все их содержимое и подкаталоги):

 wr_we_LP02323_Full lop_KLOFJ9_ffj_Full we-Paaaf_ww_fl_Full kl_wt-we-w_kl9-9FZA_Full 

Насколько я понимаю, rsync не поддерживает регулярные выражения, поэтому прежде всего это нужно сделать с помощью find (поправьте меня, если я ошибаюсь). Но как я могу сделать это таким образом, чтобы убедиться, что все каталоги и подкаталоги проверены и все соответствующие папки скопированы, даже если они очень глубоко скрыты в нескольких подкаталогах (обратите внимание, что приведенный выше пример был упрощенным структура моей оригинальной папки).

Итак, есть два вопроса:

  • Как я могу предоставить список шаблонов для find ?
  • Как я могу передать результаты find в rsync ?

Пока что это приходит мне в голову, чтобы соответствовать Full :

find . -regextype sed -regex ".*/.*[^DAT]Full$"

Но как я могу добавить список идентификаторов в эту команду find ?

Используя файл строк, которые должны присутствовать в именах каталогов, цикл над ними и цикл rsync (при условии, что мы хотим скопировать из каталога в переменной $source и в каталог в переменной $target ):

 while IFS= read -r string; do rsync --archive --exclude='*DAT*/' --include='*/' --include="*$string*_Full/***" --exclude='*' \ --prune-empty-dirs "$source"/ "$target" done  

Что делает опция rsync (первый удар по любому из шаблонов исключения / включения имеет значение):

  • --archive : Копирует собственность, разрешения, метки времени и т. д.
  • --exclude='*DAT*/' : исключить любой каталог с именем DAT .
  • --include='*/' : рассмотреть все каталоги (кроме исключенных предыдущим шаблоном). Это необходимо для того, чтобы rsync достиг нужных вам каталогов.
  • --include="*$string*_Full/***" : Рассмотрим все каталоги, соответствующие данному шаблону, и все, что находится под этим каталогом. Если $string - это --include="*parrot*_Full/***" , это будет --include="*parrot*_Full/***" .
  • --exclude='*' : не учитывайте ничего, что еще не было явно включено.
  • --prune-empty-dirs : не переносить каталоги, в которых ничего явно не включено.

Если вы хотите увидеть, как rsync оценивает шаблоны при запуске, добавьте -vv в командную строку rsync .

Тестирование:

 $ tree . |-- from | `-- a | `-- b | |-- c_A_DATFull | | `-- file | |-- c_A_DAT_Full | | `-- file | |-- c_A_Full | | `-- file | |-- c_B_DATFull | | `-- file | |-- c_B_DAT_Full | | `-- file | |-- c_B_Full | | `-- file | |-- c_C_DATFull | | `-- file | |-- c_C_DAT_Full | | `-- file | `-- c_C_Full | `-- file `-- strings.txt 12 directories, 10 files $ cat strings.txt A B $ source=from $ target=to 

(здесь работает цикл)

 $ tree . |-- from [...] `-- to `-- a `-- b |-- c_A_Full | `-- file `-- c_B_Full `-- file 17 directories, 12 files 

С помощью одного вызова rsync :

 set -- --exclude='*DAT*/' --include='*/' while IFS= read -r string; do set -- "$@" --include="*$string*_Full/***" done  

find решение:

 set -- while IFS= read -r string; do set -- "$@" -o -name "*$string*_Full" done  

Это позволит использовать find для генерации списка подкаталогов, которые вы хотите скопировать. Они передаются небольшому встроенному скрипту, который зацикливается на них.

На каждой итерации цикла создается соответствующий каталог на цели (это предполагает локальное копирование), и каталог копируется с помощью rsync .

Никогда не используйте find для передачи путей к какой-либо другой команде, если вы не можете организовать безопасное разграничение путей.

Связанные с:

  • Понимание опции -exec `find`