Одной из многих функций, которые делают Groovy привлекательным языком сценариев, является встроенная поддержка аргументов командной строки через CliBuilder . Ранее я писал о CliBuilder в статьях « Настройка операторов Groovy для использования CliBuilder и явное указание свойства « args »с помощью Groovy CliBuilder» . В этой статье я расскажу о поддержке Cliovuilder в Groovy нескольких аргументов, передаваемых через один флаг командной строки.
Документация Groovy API включает в себя следующее предложение о CliBuilder :
NBSP;
Обратите внимание на использование некоторых специальных обозначений. Добавление ‘s’ к опции, которая может появляться несколько раз и имеет аргумент, или, как в этом случае, использование valueSeparator для разделения нескольких значений аргумента, приводит к возврату списка связанных значений аргумента.
Как указано в этой документации, встроенная в CliBuilder поддержка CliBuilder позволяет обрабатывать флаг анализируемой командной строки как имеющий несколько значений, и CliBuilder для ссылки на этот аргумент является добавление «s» после «короткого» имени параметра командной строки , Это делает несколько значений, связанных с одним флагом, доступными в виде набора строк, которые можно легко перебрать для доступа к нескольким значениям.
В посте « Настройка операторов Groovy для использования CliBuilder» я кратко рассмотрел функцию, поддерживающую несколько значений, передаваемых в сценарий через один аргумент командной строки. Я описал функцию в этом посте следующим образом:
Использование нескольких значений для одного аргумента также может быть очень полезным. Непосредственное использование класса Option класса CLI Apache Commons (и в частности его константного поля UNLIMITED_VALUES ) позволяет разработчику сообщить CliBuilder, что для этой опции необходимо проанализировать переменное число значений. Символ, который разделяет эти множественные значения (в этом примере — обычное), также должен быть указан путем указания символа через ‘valueSeparator.’
Полезность этой функции Groovy с Apache CLI- питанием можно продемонстрировать, адаптировав скрипт для поиска файлов классов, содержащихся в файлах JAR, о которых я говорил в статье Поиск файлов JAR с помощью Groovy . Сценарий в этом посте рекурсивно искал в одном каталоге одну указанную строку, содержащуюся как запись в найденных файлах JAR. Несколько незначительных изменений в этом скрипте изменяет его так, что он может поддерживать несколько указанных каталогов для рекурсивного поиска нескольких выражений.
Пересмотренный сценарий показан далее.
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
#!/usr/bin/env groovy/** * findClassesInJars.groovy * * findClassesInJars.groovy -d <<root_directories>> -s <<strings_to_search_for>> * * Script that looks for provided String in JAR files (assumed to have .jar * extensions) in the provided directory and all of its subdirectories. */def cli = new CliBuilder( usage: 'findClassesInJars.groovy -d <root_directories> -s <strings_to_search_for>', header: '\nAvailable options (use -h for help):\n', footer: '\nInformation provided via above options is used to generate printed string.\n')import org.apache.commons.cli.Optioncli.with{ h(longOpt: 'help', 'Help', args: 0, required: false) d(longOpt: 'directories', 'Two arguments, separated by a comma', args: Option.UNLIMITED_VALUES, valueSeparator: ',', required: true) s(longOpt: 'strings', 'Strings (class names) to search for in JARs', args: Option.UNLIMITED_VALUES, valueSeparator: ',', required: true)}def opt = cli.parse(args)if (!opt) returnif (opt.h) cli.usage()def directories = opt.dsdef stringsToSearchFor = opt.ssimport java.util.zip.ZipFileimport java.util.zip.ZipExceptiondef matches = new TreeMap<String, Set<String>>()directories.each{ directory -> def dir = new File(directory) stringsToSearchFor.each { stringToFind -> dir.eachFileRecurse { file-> if (file.isFile() && file.name.endsWith('jar')) { try { zip = new ZipFile(file) entries = zip.entries() entries.each { entry-> if (entry.name.contains(stringToFind)) { def pathPlusMatch = '${file.canonicalPath} [${entry.name}]' if (matches.get(stringToFind)) { matches.get(stringToFind).add(pathPlusMatch) } else { def containingJars = new TreeSet<String>() containingJars.add(pathPlusMatch) matches.put(stringToFind, containingJars) } } } } catch (ZipException zipEx) { println 'Unable to open file ${file.name}' } } } }}matches.each{ searchString, containingJarNames -> println 'String '${searchString}' Found:' containingJarNames.each { containingJarName -> println '\t${containingJarName}' }} |
В строках с 11 по 28 применяется внутренний CliBuilder Groovy. Флаги командной строки ‘directoryies’ (короткое имя ‘d’) и ‘strings’ (короткое имя ‘s’) устанавливаются в строках 20 и 21. Эти строки используют Option.UNLIMITED_VALUES для указания нескольких значений, применимых для каждый аргумент, и они также используют valueSeparator для указания токена, разделяющего несколько значений для каждого флага (запятая в этих случаях).
Строки 27-28 получают несколько значений для каждого аргумента. Хотя параметры имели короткие имена «d» и «s», добавление «s» к каждому из них (теперь «ds» и «ss») позволяет получить доступ к их множественным значениям. Остальная часть сценария использует их и выполняет итерацию по нескольким строкам, связанным с каждым флагом.
Следующий снимок экрана демонстрирует выполнение вышеуказанного сценария.
Приведенный выше снимок экрана демонстрирует полезность предоставления нескольких значений для одного флага командной строки. Встроенная в Groovy поддержка Apache CLI упрощает использование настраиваемого анализа командной строки.
Ссылка: Groovy: несколько значений для одного параметра командной строки от нашего партнера по JCG Дастина Маркса в блоге Inspired by Actual Events .
