Я пытаюсь запустить rsync для рекурсивного копирования некоторых файлов по пути на основе их шаблона имени файла без учета регистра . Вот что я сделал для запуска rsync:
$ rsync -avvz --include ='*/' --include='.*[Nn][Aa][Mm][E].*' --exclude='*' ./a/ ./b/
Ничего не копируется, вывод отладки показывает:
[sender] hiding file 1Name.txt because of pattern *
[sender] hiding file 1.txt because of pattern *
[sender] hiding file 2.txt because of pattern *
[sender] hiding file Name1.txt because of pattern *
[sender] hiding directory test1 because of pattern *
[sender] hiding file NaMe.txt because of pattern *
Я пытался использовать: --include='*[Nn][Aa][Mm][E]*'
и другие комбинации, но это все еще не идет.
Любые идеи о том, как использовать регулярные выражения для включения некоторых файлов?
--exclude='*'
?Ответы:
Rsync не говорит регулярных выражений. Вы можете подключить find и grep, хотя это немного загадочно. Чтобы найти целевые файлы:
Но все они имеют префикс «a /», что имеет смысл, но в итоге мы хотим получить список шаблонов включения, приемлемых для rsync, и, поскольку префикс «a /» не работает для rsync I ' уберу это с вырезом:
Проблема все еще существует - мы все равно будем пропускать файлы в подкаталогах, потому что rsync не ищет каталоги в списке исключений. Я собираюсь использовать awk для добавления подкаталогов любых подходящих файлов в список шаблонов включения:
Осталось только отправить список в rsync - мы можем использовать аргумент --include-from = - для предоставления списка шаблонов rsync при стандартном вводе. Итак, в целом:
Обратите внимание, что на исходный каталог «a» ссылаются через два разных пути - «a /» и «./a/». Это тонко, но важно. Чтобы сделать вещи более согласованными, я собираюсь сделать одно последнее изменение и всегда ссылаться на исходный каталог как «./a/». Тем не менее, это означает, что команда cut должна измениться, так как перед результатами поиска будет добавлено «./»:
источник
-t
это действительный переключатель.sed "s#^$1/*##"
buuuut, который будет разбиваться на пути, содержащие #. Чтобы исправить это, мы должны процитировать имя входящего каталога:prefix=$(echo "$1" | sed 's#/#\\/#g')
и тогдаsed "s/^$prefix\\/*//"
субтили bash-цитирования немного кошмарны;)Я бы предложил использовать параметр фильтра rsync. Для вашего примера просто введите:
первое правило фильтра сообщает rsync, какие шаблоны нужно включить. Второе правило необходимо, чтобы rsync проверил все каталоги на предмет его обхода. Чтобы предотвратить включение пустых папок, они исключаются явно по
-m
выбору. Последнее правило фильтра указывает rsync удалить все оставшиеся шаблоны, которые до сих пор не совпадали.источник
Если вы используете ZSH, то можете использовать флаг (#i), чтобы отключить чувствительность к регистру. Пример:
ZSH также поддерживает исключения, которые задаются так же, как обычный путь, но имеют начальный ~
Вы можете связать исключения:
Наконец, вы можете указать, какой тип файла вы хотите вернуть (каталог, файл и т. Д.). Это делается с помощью (/) для каталога и (.) Для файла.
Исходя из всего этого, я бы сделал эту команду как:
(Я не вижу необходимости исключения из этих селекторов)
источник
Ответ @ sqweek выше удивителен, хотя я подозреваю, что в его
awk
скрипте есть ошибка при создании родительских каталогов, например:Я смог исправить это, используя
gensub
вместо этого:Таким образом, его полное решение с
awk
измененным битом будет:источник
sub("/[^/]*$")
).Пробовал с C # скрипт, так как это язык, с которым у меня больше всего опыта. Я могу создать список файлов, которые я хочу включить, но кто-то rsync все еще говорит мне, чтобы я пошел в поход. Он создает папки, но игнорирует файлы. Вот что я получил ..
Сначала содержание каталога:
Затем вывод сценария C #:
И вывод отладки:
источник
[РЕДАКТИРОВАТЬ] Это работает только локально. Для удаленных путей сначала необходимо создать структуру каталогов.
Более простой, чем принятый ответ; Используйте --file-from, который автоматически включает родительские каталоги, и печатайте путь к файлу с% P
Так что вам нужно только использовать
find
иrsync
.источник