Я использую следующий bash script для копирования только файлов определенного расширения (в данном случае *.sh), однако он все же копирует все файлы. что не так?
from=$1 to=$2 rsync -zarv --include="*.sh" $from $to
Я использую следующий bash script для копирования только файлов определенного расширения (в данном случае *.sh), однако он все же копирует все файлы. что не так?
from=$1 to=$2 rsync -zarv --include="*.sh" $from $to
Я думаю, что --include
используется для включения подмножества файлов, которые в противном случае исключены --exclude
, вместо того, чтобы включать только эти файлы. Другими словами: вы должны думать о включении смысла , не исключайте.
Попробуйте вместо этого:
rsync -zarv --include "*/" --exclude="*" --include="*.sh" "$from" "$to"
Для версии rsync 3.0.6 или выше порядок необходимо изменить следующим образом (см. Комментарии):
rsync -zarv --include="*/" --include="*.sh" --exclude="*" "$from" "$to"
Добавление флага -m
позволит избежать создания пустых структур каталога в пункте назначения. Протестировано в версии 3.1.2.
Поэтому, если мы хотим только файлы *.sh, мы должны исключить все файлы --exclude="*"
, включить все каталоги --include="*/"
и включить все *.sh файлы --include="*.sh"
,
Вы можете найти несколько хороших примеров в разделе " Включить/исключить правила шаблона" на странице руководства
Ответ @chepner будет копировать все подкаталоги независимо от того, содержит ли он файл или нет. Если вам нужно исключить подкаталоги, которые не содержат файл и сохраняют структуру каталогов, используйте
rsync -zarv --prune-empty-dirs --include "*/" --include="*.sh" --exclude="*" "$from" "$to"
Еще одно дополнение: если вам нужно синхронизировать файлы по своим расширениям в только в одном каталоге (без рекурсии), вы должны использовать такую конструкцию:
rsync -auzv --include './' --include '.ext' --exclude '*' /source/dir/ /destination/dir/
Обратите внимание на точку в первой --include
. --no-r
не работает в этой конструкции.
Здесь важная часть страницы man:
По мере того, как создается список файлов/каталогов для передачи, rsync проверяет каждое имя, которое будет передано по списку включенных/исключающих шаблонов, в свою очередь, и на первый соответствующий шаблон будет действовать: если это шаблон исключения, то этот файл пропускаются; если это шаблон включения, то это имя файла не пропускается; если соответствующий шаблон не найден, то имя файла не пропущено.
Подвести итоги:
Кроме того, что-то, заканчивающееся косой чертой, соответствует каталогам (например, find -type d
).
Позвольте отбросить этот ответ сверху.
rsync -zarv --prune-empty-dirs --include "*/" --include="*.sh" --exclude="*" "$from" "$to"
.sh
Наконец, --prune-empty-directories
сохраняет первое правило от пустых каталогов по всему месту.