Что означает [[: space:]] в bash?

23

Я только что натолкнулся на скрипт bash. Что [[:space:]]значит в скрипте bash? Почему двойная кишка?

Геральдин
источник

Ответы:

35

Это, действительно, в руководстве Баша, но это помогает знать , что вы ищете, что не полезно , если вы не знаете , что вы смотрите. Если бы вы искали, [[вы бы отвлеклись на [[ expression ]]раздел условных выражений. Кроме того, поиск :space:вы найдете в двух примерах в одном разделе. Вы можете следовать крошке в этом примере:

Например, следующее будет соответствовать строке (сохраненной в строке переменной оболочки), если в значении есть последовательность символов, состоящая из любого числа, включая ноль, пробелов, ноль или один экземпляр «a», затем a «Ъ»:

[[ $line =~ [[:space:]]*?(a)b ]]

... из которого можно собрать вместе , что [[:space:]]часть соответствует «пробельных символов», но вы могли бы быть прощены за то, думая , что это было только буквальный символ пробела , а не целый класс символов, который является то , что он представляет.

Если вы (случайно?) Ищите строку " space"(то есть пробел, за которым следует слово «пробел») в онлайн-руководстве по bash , «всего» нужно пройти около 32 совпадений. О десятом будет здесь:

Внутри '[' и ']' классы символов могут быть указаны с использованием синтаксиса [: class:], где class является одним из следующих классов, определенных в стандарте POSIX:

alnum   alpha   ascii   blank   cntrl   digit   graph   lower
print   punct   space   upper   word    xdigit

Класс символов соответствует любому символу, принадлежащему этому классу.

Что приведет вас к стандарту POSIX, где вы можете найти термин «класс символов» и найти

wctype, wctype_l - определяет класс персонажа , который дает вам следующее:

Функции wctype () [CX] [Option Start] и wctype_l () [Option End] должны определять значения wctype_t в соответствии с правилами набора кодированных символов, определяемыми информацией о типах символов в текущей локали [CX] [Option Start] или в локали, представленной локалью [Option End] соответственно (категория LC_CTYPE).

Если вы затем перейдете по ссылке setlocale , вы, наконец, получите свой реальный ответ в разделе Locale :

Космос

Определите символы, которые будут классифицироваться как символы пробела. В локали POSIX точно <space>, <form-feed>, <newline>, <carriage-return>, <tab>, and <vertical-tab>должно быть включено.

В файле определения локали не должно быть указано символов, заданных для ключевых слов верхний, нижний, альфа, цифра, график или xdigit. <space>, <form-feed>, <newline>, <carriage-return>, <tab>, and <vertical-tab>Портативного набора символов, и любые символы , включенные в класс заготовки автоматически включаются в этот класс.

Джефф Шаллер
источник
1
Проще найти ручное совпадение LESS=+'/Within \[ and \],' man bashвместо 32 nкоманд ext :-).
Исаак
5
@ Исаак: Я думаю, дело в том, чтобы научить человека ловить рыбу. Тем не менее, я не знал о less +"$cmd", так что спасибо за это.
Йол
3
Действительно, я ответил, учитывая точку зрения ФП; их можно простить, если они не поймут, что внешнее []не зависит от внутреннего []. Я пытался (!) Найти путь от вопроса к ответу, не зная слишком много о том, каков был ответ, хотя мне потребовалось несколько удачных предположений :)
Джефф Шаллер
17

Это не только для Bash, это часть нотации POSIX.

Что такое POSIX?

POSIX или «Портативный интерфейс операционной системы для uniX» - это набор стандартов, определяющих некоторые функции, которые должна поддерживать операционная система (UNIX). Один из этих стандартов определяет два вида регулярных выражений.

POSIX выражения в скобках

Скобки POSIX представляют собой особый вид символьных классов. Выражения в скобках POSIX соответствуют одному символу из набора символов, как классы обычных символов.

Стандартный POSIX

[[:alnum:]]   Alphanumeric characters
[[:alpha:]]   Alphabetic characters
[[:blank:]]   Space and tab
[[:cntrl:]]   Control characters
[[:digit:]]   Digits
[[:graph:]]   Visible characters (anything except spaces and control characters)
[[:lower:]]   Lowercase letters
[[:print:]]   Visible characters and spaces (anything except control characters)
[[:punct:]]   Punctuation (and symbols).
[[:space:]]   All whitespace characters, including line breaks
[[:upper:]]   Uppercase letters
[[:xdigit:]]  Hexadecimal digits

Стандарты отсутствуют

[[:ascii:]]   ASCII characters
[[:word:]]    Word characters (letters, numbers and underscores)

устаревший синтаксис (может кто-нибудь найти ссылку на них?)

[[:<:]]       Start of Word 
[[:>:]]       End of Word

Вы можете найти больше информации здесь: вики

Нима
источник
1
[[:ascii:]]и [[:word:]]не являются классами POSIX (они кажутся bashспецифичными для), и я не могу найти [[:<:]]ни того, ни [[:>:]]другого. Лучшей
Кусалананда
1
Да, [[:ascii:]]и не [[:word:]]являются стандартными классами POSIX. для [[:<:]]и [[:>:]]я не могу найти никаких ссылок, но это то же самое \b. en.wikipedia.org/wiki/Regular_expression#Character_classes
Нима
Postgres определяет использование [[:<:]]и утверждает, что: Это расширение, совместимое, но не указанное в POSIX 1003.2
Исаак
[[:<:]]тоже во FreeBSD, с тем же предупреждением, что и в PostgreSQL: freebsd.org/cgi/…
ilkkachu
1
А [[:ascii:]]и [[:word:]], конечно же, работа в Bash в сопоставлении с образцом, но не в регулярных выражениях (по крайней мере , в моей системе, я думаю , что Bash использует библиотеку регулярных выражений системы). Ба.
ilkkachu
9

В регулярных выражениях и глобусах / шаблонах имен файлов эта [...]конструкция соответствует любому одному из символов, перечисленных в скобках. В этих скобках можно использовать ряд именованных классов символов стандартных символов . Одним из них является то [:space:], что соответствует пробельным символам (как \sв регулярных выражениях Perl). Смотрите, например, Pattern Matching в руководстве Bash.

Таким образом, [[:space:]]является частью регулярного выражения или сопоставления с шаблоном, которое соответствует только пробелу.

Например, сопоставление с образцом (стандартная оболочка, а не специфичная для Bash):

case $var in 
    *[[:space:]]*) echo "'$var' contains whitespace";;
esac

или регулярное выражение (Bash):

if [[ $var =~ [[:space:]] ]]; then
    echo "'$var' contains whitespace"
fi

Обратите внимание, что хотя выражения в скобках [...]работают одинаково в регулярных выражениях и шаблонах оболочки, они, как правило, во многом не совпадают. ( caseи [[ string == pattern ]]использовать сопоставления с образцом, [[ string =~ regex ]]использует регулярные выражения.)

Регулярные выражения также не являются специфичными для оболочки, они используются, например, awkи так sedже, и описаны, например, в справочной странице Linuxregex(7)

ilkkachu
источник