Intereting Posts

Ограничение поддержки символов ZSH, поддерживающее повторение?

Кто-нибудь знает, есть ли способ включить ограничения повторения в выражения подстановки ZSH?

Например, чтобы соответствовать всем файлам, начинающимся с «ABC», следующих одним или несколькими номерами, с помощью grep можно было бы:

ls | grep -e "ABC[0-9]\+" 

Есть ли способ сделать это напрямую с помощью glob-строк ZSH? Что-то вроде:

 ls "ABC[0-9]\+" 

Я просмотрел документы для ZSH и Googled для чего-то подобного, но до сих пор не нашел такой поддержки.

Кто-нибудь знает, возможно ли это?

Да, используйте ## для соответствия одному или нескольким вхождениям [0-9] например:

 ABC[0-9]## 

Для этого требуется установить extendedglob , который по умолчанию. Если он не установлен, установите его первым:

 setopt extendedglob 

Пример:

 % print -l ABC* ABC ABC75475 ABC8 ABC90 % print -l ABC[0-9]## ABC75475 ABC8 ABC90 

С включенным extendedglob :

 $ setopt extendedglob $ print -rl -- perl[[:digit:]]## perl5 

или с включенным bareglobqual отключенным bareglobqual :

 $ setopt kshglob $ unsetopt bareglobqual $ print -rl -- perl+([[:digit:]]) perl5 

Обратите внимание, что используя [:digit:] чтобы совместить все считанные цифры в текущей локали. Если вы хотите LC_ALL=C только LC_ALL=C , установите LC_ALL=C или используйте буквально [0123456789] .


Вы можете указать количество совпадений, например, регулярное выражение {n,m} используя (#cN,M) флаг globbing в любом месте, ## могут использоваться операторы # и ## , за исключением (*/)# и (*/)## :

 $ print -rl -- perl[[:digit:]](#c1) perl5 $ print -rl -- perl[[:digit:]](#c2) zsh: no matches found: perl[[:digit:]](#c2) 

Прокрутите вниз до « Генерация имени файла » и включите либо extended_glob (который должен быть по умолчанию, но не для обратной совместимости) или ksh_glob . Оба расширенных глосса zsh и ksh имеют полную силу регулярных выражений.

 ERE syntax ksh glob zsh extended glob (foo)* *(foo) (foo)# (foo)+ +(foo) (foo)## (foo)? ?(foo) (|foo) (foo|bar) @(foo|bar) (foo|bar) 

Имейте в виду, что большинство инструментов, которые используют регулярные выражения, используют их как шаблоны поиска , которые должны соответствовать подстроке, но глобусы всегда используются как шаблоны, которые должны соответствовать всей строке. Например, foofoobar не соответствует zsh glob (foo)## , так как после foofoo текст.

Zsh имеет дополнительные операторы, которые не распространяют выразительную силу, но облегчают запись некоторых выражений. Операторы ^ и ~ ( extended_glob ) и !(…) ( ksh_glob ) обеспечивают отрицание, например ^foo или !(foo) соответствует чему угодно, кроме foo , что в синтаксисе regex требует громоздких |[^f].*|f[^o].*|fo[^o].* . Оператор <…-…> (zsh-specific, не требует extended_glob ) соответствует любому целому (в десятичной нотации) в диапазоне, например <3-11> соответствует 3 и 10 но не 30 или 1 .

Таким образом, исключая такие проблемы, как непечатаемые символы, ls | grep -e "ABC[0-9]\+" ls | grep -e "ABC[0-9]\+" может быть написана способами, такими как

 print -lr -- *ABC[0-9]##*(N) # requires extended_glob print -lr -- *ABC+([0-9])*(N) # requires ksh_glob print -lr -- *ABC+<->(N) 

Но так как «одна или несколько цифр, то что-нибудь» эквивалентно «цифре, чем угодно», ее также можно записать

 print -lr -- *ABC[0-9]*(N)