Этот ответ основан на приведенном выше ответе, который очень похож на 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).
Вы можете запустить 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
У вас уже есть подходящий ответ, и это нормально. Я хотел обратиться к другой части вашего вопроса, которая спрашивает, почему функциональность --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"
Правила фильтрации говорят, что по порядку:
foo
, которые находятся в каталоге с именемdata
ниже исходного пути . *.zip
файлы (или каталоги ). Первое включение будет соответствовать /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