Поддиректории, специфичные для rsync, с сопоставлением с образцом

Этот ответ основан на приведенном выше ответе, который очень похож на JSON, поэтому я ' Поэтому мы предположили, что это, вероятно, JSON . Но в вашем образце он неполный, что, как я полагаю, является опечаткой. Если это не так ... ну, у вас уже есть ответы sed .

Пожалуйста, не используйте регулярное выражение для синтаксического анализа JSON . Это мерзко. regex плохо работает с рекурсивными типами данных с тегами, такими как JSON / XML . В лучшем случае это грязный хакер, который в будущем создаст хрупкий код.

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

Предположим, что JSON подобен этому (использовался http://jsonlint.com/ для очистки элементов)

{
    "s220823vaps2512": {
        "hostname": "s220823vaps2512",
        "description": "data",
        "type": "Virtual",
        "os": "data",
        "idc": "data",
        "environment": "data",
        "deviceclass": "data",
        "cores": "data",
        "memory": "data",
        "frontnet": "data",
        "ipset": {
            "backnet": "data",
            "storagenet": "data",
            "metroclusternet": "data"
        },
        "roles": "data",
        "mounts": "data"
    },
    "s220823vaps2513": {
        "hostname": "s220823vaps2513",
        "description": "data",
        "type": "Virtual",
        "os": "data",
        "idc": "data",
        "environment": "data",
        "deviceclass": "data",
        "cores": "data",
        "memory": "data",
        "frontnet": "data",
        "ipset": {
            "backnet": "data",
            "storagenet": "data",
            "metroclusternet": "data"
        }
    }
}

Тогда способ просто получить нужные биты:

#!/usr/bin/env perl
use strict;
use warnings;

use JSON;

my $input = ### as above, snipped for brevity. 

#decode/validated
my $json = decode_json ( $input );
#create new JSON array of elements. 
my $new_json = [map { $json -> {$_} } keys %$json];
#print it out. 
print to_json ( $new_json, { pretty => 1, canonical => 1 } );

И таким образом вы создаете допустимый вывод JSON, а также обрабатываете случаи, когда, например, порядок ключей другой (который полностью действителен в JSON).

1
28.04.2018, 23:12
2 ответа

Вы можете запустить rsync таким образом:

rsync --dry-run -av --human-readable --stats --progress --exclude="*.zip" /path/to/data/foo* /path/to/copy/to/

возможно, вы захотите сократить команду таким образом:

rsync  -avhn --stats --progress --exclude="*.zip" /path/to/data/foo* /path/to/copy/to/

цитата из man rsync

-a, --archive               archive mode; equals -rlptgoD (no -H,-A,-X)

-v, --verbose               increase verbosity

-h, --human-readable        output numbers in a human-readable format

-n, --dry-run               perform a trial run with no changes made

, когда будете готовы, запустите команду без-n

с этим аргументом также можно сохранить лог-файл:

--log-file=

, поэтому приведенная выше команда rsync станет:

rsync  -avhn --stats --progress --exclude="*.zip" --log-file=logfile.log /path/to/data/foo* /path/to/copy/to/

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

--log-file=/path/to/logfile
2
27.01.2020, 23:43

У вас уже есть подходящий ответ, и это нормально. Я хотел обратиться к другой части вашего вопроса, которая спрашивает, почему функциональность --includeне работает так, как вы ожидаете.

Прежде всего, давайте посмотрим, как работают фильтры --includeи --exclude.

  • aaaбудет применяться к любому файлу или каталогу с именемaaa
  • /aaaбудет применяться к любому файлу или каталогу с именем aaaв начале исходного пути
  • aaa/будет применяться к любому каталогу с именемaaa

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

Операции включения и исключения обрабатываются слева направо (первая операция важнее второй, а вторая важнее третьей ).

Теперь давайте посмотрим на ваш конкретный пример:

rsync -ah --include="data/foo*" --exclude="*.zip" --exclude="*" "/path/to/data" "/mnt/backup/drive"

Правила фильтрации говорят, что по порядку:

  1. Включить все файлы или каталоги, имя которых начинается с foo, которые находятся в каталоге с именемdataниже исходного пути .
  2. Исключить все *.zipфайлы (или каталоги ).
  3. Исключите все, что мы еще не упомянули.

Первое включение будет соответствовать /path/to/data/data/foo1, но не будет соответствовать /path/to/data/foo1. Подозреваю, что это основное недоразумение.

Вы можете сопоставить свои /foo*каталоги с очень похожим решением:

rsync -ah --include="/foo*/" --exclude="*.zip" --exclude="*" "/path/to/data/" "/mnt/backup/drive"

Но на самом деле,если бы я писал это, я бы, вероятно, включил каталоги /foo*в спецификацию исходного пути (, обратите внимание, что foo*не заключен в кавычки, поэтому оболочка может получить подстановочный знак )и беспокоиться только об исключении нежелательных zip-файлов:

rsync -ah --exclude="*.zip" /path/to/data/foo*/ /mnt/backup/drive
1
27.01.2020, 23:43

Теги

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