Используя rsync, как может, я знаю, какой атрибут исходного файла отличался от dest, который вызвал trasfer

Вы можете использовать find , чтобы найти все файлы в дереве каталогов, которые соответствуют (или не соответствуют) некоторым конкретным тестам, а затем что-то с ними сделать. Для этой конкретной проблемы вы можете использовать:

find -type f ! \( -iname '*.png' -o -iname '*.gif' -o -iname '*.jpg' -o -iname '*.xcf' \) -exec echo mv {} /new/path \;

Это ограничивает поиск обычными файлами ( -тип f ), а затем файлами, имена которых не имеют (! ) расширение *. png в любом регистре ( -iname '* .png' ) или ( -o ) *. gif , и скоро. Все расширения сгруппированы в одно условие между \ (... \) . Для каждого совпадающего файла он запускает команду ( -exec ), которая перемещает файл, имя которого вставлено вместо {} , в каталог / new / путь . \; сообщает find , что команда завершена.

Замена имени происходит внутри кода выполнения программы, поэтому пробелы и другие специальные символы не имеют значения.


Если вы хотите сделать это прямо внутри Bash, вы можете использовать расширенные возможности Bash сопоставления с образцом . Для этого необходимо, чтобы shopt extglob был включен, а также globstar . В этом случае используйте:

mv **/!(*.[gG][iI][fF]|*.[pP][nN][gG]|*.[xX][cC][fF]|*.[jJ][pP][gG]) /new/path

Это соответствует всем файлам в подкаталогах ( ** ), которые не соответствуют *. Gif , *. Png и т. Д. , в любой комбинации наборов символов и перемещает их на новый путь. Расширение выполняется оболочкой, поэтому пробелы и специальные символы снова не имеют значения.

Выше предполагается, что все файлы находятся в подкаталогах. В противном случае вы можете повторить часть после ** / , чтобы также включить текущий каталог.

Подобные функции есть в zsh и других оболочках, но вы указали, что используете Bash.


(Еще одно примечание: синтаксический анализ ls никогда не бывает хорошей идеей - просто не пытайтесь.)

1
22.10.2014, 15:55
1 ответ

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

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

Если вы можете работать с инструментом, который сравнивает два дерева и сообщает о различиях и интерполирует его вывод в соответствии с вашими потребностями, тогда mtreeможет подойти для ваших нужд.

mtreeспециально разработан для сравнения двух деревьев каталогов и сообщения о различиях.

На исходном компьютере создайте спецификацию mtree (, включая хэш sha256 )желаемого исходного дерева:

# mtree -K sha256 -cp /my_path > my_path.mtree

Затем rsyncпросмотрите дерево и запустите mtree на удаленной машине, чтобы увидеть, совпадает ли путь дерева удаленных каталогов /remote _с локальным путем /my _:

# rsync -a --delete /my_path/ remote:/remote_path/
# ssh remote mtree -p /remote_path < my_path.mtree && echo match
match

Теперь давайте немного повозимся с удаленным деревом. Короче говоря, я создал целевой файл farkle, которого не существует в источнике, удалил файл file.txtи изменил метку времени в файле data.txt.

# ssh remote mtree -p remote_path < my_path.mtree || echo fail
.:      modification time (Wed Apr 17 10:49:32 2019, Wed Apr 17 11:55:10 2019)
extra: farkle
data.txt: 
        modification time (Wed Apr 17 10:45:02 2019, Wed Apr 17 11:56:27 2019)
foo:    size (32, 29)
        modification time (Tue Apr 16 10:16:44 2019, Wed Apr 17 11:53:18 2019)
        sha256digest (0x6082aa7261362c4c71c82adf492bc724de53a5814e64b233c43c6775efeb1dd0, 0x2d2537ea27c27dfb2c1690c51c652b9ada32adc29a91b732c24939dcff371cd6)
./file.txt missing
fail

mtreeсообщает вам, что:

  • farkleсуществует в пункте назначения, но не в источнике; это было бы удаляется, если вы укажете --удалить в командной строке rsync.
  • data.txtне изменился ни по содержимому (, ни по хэшу sha256 ), ни по размеру, но более новая временная метка; копирование, основанное только на контрольной сумме, может не -повторно передать файл, а также rsyncне передать только «более новые» файлы, поскольку файл назначения теперь новее, чем исходный.
  • file.txtотсутствует на целевом хосте и, предположительно, rsyncбудет передано при следующем запуске, если не будет какого-либо критерия исключения.

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

Если вы методично сохраните выходной файл my_path.mtree, например, включив в имя файла отметку даты, вы также можете запустить mtreeна локальном компьютере, чтобы сравнить существующее дерево путей /my _с предыдущим запуском. (вчерашний? на прошлой неделе? ), чтобы увидеть, не изменилось ли что-то локально, чего вы, возможно, не ожидали.

mtreeвключен в некоторые дистрибутивы Unix,но если у вас отсутствует mtree, мне удалось установить версию Арчи Коббса с GitHub .

1
27.01.2020, 23:51

Теги

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