«zsh массив параметров» в руководстве я не могу полностью понять. Кто-нибудь может объяснить это, приводя примеры? - PullRequest
0 голосов
/ 13 марта 2020

Единственное, что я мог понять, это "$ FOO [2,5]". но варианты r, R, s, w Я не знаю четко, как их использовать в реальных задачах:

'zsh' сайт говорит: (http://zsh.sourceforge.net/Doc/Release/Parameters.html#Parameters)

Параметры массива

Значение параметра массива может быть назначено записью:

name = (значение ...) ...

Отдельные элементы массива может быть выбран с использованием нижнего индекса. Подстрочный индекс вида [exp] выбирает отдельный элемент exp, где exp - это арифметическое выражение c, которое будет подвергаться расширению arithmeti c, как если бы оно было окружено $ ((...)). Элементы нумеруются, начиная с 1, если опция KSH_ARRAYS не установлена, когда они нумеруются с нуля.

Индекс в форме [] или [@] вычисляется для всех элементов массива; между ними нет разницы, за исключением случаев, когда они появляются в двойных кавычках. "$ foo []" оценивается как "$ foo [1] $ foo [2] ...", тогда как "$ foo [@]" оценивается как "$ foo [1]" "$ foo [2] ", et c.

Индекс вида [exp1, exp2] выбирает все элементы в диапазоне от exp1 до exp2 включительно. Если один из индексов оценивается как отрицательное число, скажем, -n, то используется n-й элемент из конца массива. Таким образом, $ foo [-3] является третьим элементом в конце массива foo, а $ foo [1, -1] совпадает с $ foo [*].

Подписка также может выполняться для не массив значений, в этом случае нижние индексы указывают подстроку для извлечения Например, если для FOO задано значение foobar, то echo $ FOO [2,5] печатает ooba.

Подписки могут использоваться внутри фигурных скобок, используемых для разграничения имени параметра, поэтому $ {foo [2]} эквивалентно $ foo [2]. Если установлена ​​опция KSH_ARRAYS, то будет работать только фигурная форма, иначе индекс не будет обрабатываться специально.

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

Если после открывающей скобки или запятой сразу следует открывающая скобка, то строка до соответствующей закрывающей скобки считается списком флагов. В настоящее время понятны следующие флаги:

e Эта опция не имеет никакого эффекта и сохраняется только для обратной совместимости. w Если параметр subscripted является скалярным, тогда этот флаг заставляет подписку работать на основе отдельных слов вместо символов. s: string: определяет строку, которая разделяет слова (для использования с флагом w). p Распознать те же escape-последовательности, что и встроенную печать в строковом аргументе последующего флага s. f Если параметр subscripted является скалярным, тогда этот флаг заставляет подписку работать отдельно для каждой строки вместо символов. Это сокращение для pws: \ n :. r Если указан этот флаг, exp берется в качестве шаблона, а результатом является первый соответствующий элемент массива, подстрока или слово (если параметр является массивом, если он является скаляром, или если это скаляр и флаг w дается соответственно); обратите внимание, что это похоже на указание числа: $ foo [(r) ??, 3] и $ foo [(r) ??, (r) f *] работают. R Вроде г, но дает последний матч. Мне нравится r, но вместо этого выдается индекс совпадения; это не может сочетаться со вторым аргументом. Мне нравится я, но дает индекс последнего матча. n: expr: в сочетании с r, R, i или I заставляет их возвращать n-ое или n-е последнее совпадение (если expr имеет значение n).

1 Ответ

1 голос
/ 13 марта 2020

Не уверен, откуда вы цитируете, так как этот текст не появляется на странице, на которую вы ссылаетесь. Вот несколько примеров этих флагов в действии:

# If the parameter subscripted is a scalar
foo="The quick brown fox jumps over the lazy dog"
echo $foo[2]
# => h       (the second character)
echo $foo[(w)2]
# => quick   (the second word)
echo $foo[(ws:fox:)2]
# =>  jumps over the lazy dog    (the second "word", but delimited by "fox", not space)
echo $foo[(wr)*az*]
# => lazy    (the first word that matches the pattern "*az*")
echo $foo[(wR)?????]
# => jumps   (the last word that matches the pattern "?????")
echo $foo[(wrn.2.)???]
# => fox     (the second three-letter word)
echo $foo[(wrin.2.)???]
# => 17      (the index of second three-letter word)

# If the parameter subscripted is an array
foo=("The quick brown fox" jumps "over the lazy dog")
echo $foo[1]
# => The quick brown fox    (The first element)
echo $foo[(r)*the*dog]
# => over the lazy dog      (The first element that matches the pattern "*the*dog")

Для более реальной проблемы, предположим, у меня есть файл .pass, который содержит

DB_NAME=mydb
DB_USER=me
DB_PASS=not real password
DB_HOST=localhost
DB_PORT=5432

Затем это будет читаться в ваш пароль без использования внешних утилит, таких как grep, sed или awk:

file=$(<.pass)                # read in the file contents
line=$file[(fr)DB_PASS=*]     # find the line (f) that matches pattern (r)
pass=$line[(ws:=:)2]          # get the second (2) segment (w) split by "=" (s:=:)
...