¿Cuál es el significado de [[: espacio:]] en bash?

23

Acabo de encontrar un script bash. ¿Qué [[:space:]]significa en un script bash? ¿Por qué el doble colon?

geraldin
fuente

Respuestas:

35

De hecho, está en el manual de bash, pero ayuda a saber lo que está buscando, lo que no es útil si no sabe lo que está viendo. Si buscas [[te distraerás con la [[ expression ]]sección de expresión condicional. Además, la búsqueda :space:te aterriza en dos ejemplos en la misma sección. Puede seguir la ruta de navegación en ese ejemplo:

Por ejemplo, lo siguiente coincidirá con una línea (almacenada en la línea variable del shell) si hay una secuencia de caracteres en el valor que consiste en cualquier número, incluido cero, de caracteres de espacio, cero o una instancia de 'a', luego un 'si':

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

... a partir de la cual podría juntar que la [[:space:]]porción correspondía a "caracteres espaciales", pero podría ser perdonado por pensar que era solo un carácter espacial literal y no una clase completa de caracteres, que es lo que representa.

Si (¿sucede?) Busca la cadena " space"(es decir, un espacio seguido de la palabra "espacio") en el manual de bash en línea , hay "solo" unas 32 coincidencias por recorrer. Alrededor del décimo estará aquí:

Dentro de '[' y ']', las clases de caracteres se pueden especificar utilizando la sintaxis [: class:], donde class es una de las siguientes clases definidas en el estándar POSIX:

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

Una clase de personaje coincide con cualquier personaje que pertenezca a esa clase.

Lo que luego lo llevaría al estándar POSIX donde podría buscar el término "clase de caracteres" y encontrar

wctype, wctype_l: define la clase de caracteres , que te lleva hasta:

Las funciones wctype () [CX] [Opción de inicio] y wctype_l () [Opción de finalización] determinarán los valores de wctype_t de acuerdo con las reglas del conjunto de caracteres codificados definidos por la información del tipo de caracteres en la configuración regional actual [CX] [Opción de inicio] o en la configuración regional representada por configuración regional, [Opción Fin] respectivamente (categoría LC_CTYPE).

Si luego seguiste el enlace setlocale , finalmente llegarías a tu respuesta real, en la sección Configuración regional :

espacio

Defina caracteres para clasificarlos como espacios en blanco. En el entorno local POSIX, se <space>, <form-feed>, <newline>, <carriage-return>, <tab>, and <vertical-tab>incluirá exactamente .

En un archivo de definición de configuración regional, no se especificará ningún carácter para las palabras clave superior, inferior, alfa, dígito, gráfico o xdigit. La <space>, <form-feed>, <newline>, <carriage-return>, <tab>, and <vertical-tab>del conjunto de caracteres portátil y los caracteres incluidos en el espacio en blanco de la clase se incluyen automáticamente en esta clase.

Jeff Schaller
fuente
1
Es más fácil encontrar la coincidencia manual con en LESS=+'/Within \[ and \],' man bashlugar de 32 ncomandos ext :-).
Isaac
55
@ Isaac Creo que el punto es enseñarle al hombre a pescar. Dicho esto, no lo sabía less +"$cmd", así que gracias por eso.
JoL
3
De hecho, respondí dada la perspectiva del OP; podrían ser perdonados por no reconocer que lo externo []es independiente de lo interno []. Traté (!) De encontrar un camino desde la pregunta hasta la respuesta sin saber demasiado sobre cuál era la respuesta, aunque me costó adivinar con suerte :)
Jeff Schaller
17

No es solo para Bash, es parte de la notación POSIX.

¿Qué es POSIX?

POSIX o "Interfaz del sistema operativo portátil para uniX" es una colección de estándares que definen algunas de las funcionalidades que un sistema operativo (UNIX) debe soportar. Uno de estos estándares define dos sabores de expresiones regulares.

Expresiones de soporte POSIX

Las expresiones de paréntesis POSIX son un tipo especial de clases de caracteres. Las expresiones de paréntesis POSIX coinciden con un carácter de un conjunto de caracteres, al igual que las clases de caracteres normales.

POSIX estándar

[[: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

Ninguna norma

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

sintaxis heredada (¿alguien puede encontrar referencias a estos?)

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

Puedes encontrar más información aquí: wiki

Nima
fuente
1
[[:ascii:]]Y [[:word:]]no son POSIX clases (que parecen ser bashespecífica de), y no puedo encontrar [[:<:]]ni [[:>:]]tampoco. Una mejor referencia puede haber sido pubs.opengroup.org/onlinepubs/9699919799/basedefs/…
Kusalananda
1
Sí, [[:ascii:]]y [[:word:]]no son clases POSIX estándar. para [[:<:]]y [[:>:]], no puedo encontrar ninguna referencia, pero es lo mismo \b. en.wikipedia.org/wiki/Regular_expression#Character_classes
Nima
Postgres define el uso de [[:<:]]y afirma que: Esta es una extensión, compatible pero no especificada por POSIX 1003.2
Isaac
[[:<:]]está en FreeBSD también, con la misma salvedad que tiene PostgreSQL: freebsd.org/cgi/...
ilkkachu
1
Y [[:ascii:]]y [[:word:]]del trabajo del curso en Bash en concordancia con el modelo, pero no en expresiones regulares (al menos en mi sistema, creo Bash utiliza la biblioteca de expresiones regulares del sistema). Bah.
ilkkachu
9

En expresiones regulares y nombres de archivo globos / patrones de shell, el [...] construcción coincide con cualquier carácter de los que figuran entre paréntesis. Dentro de esos corchetes, se pueden usar varias clases de caracteres de caracteres estándar con nombre . Uno de ellos es [:space:], que coincide con los espacios en blanco (como \sen las expresiones regulares de Perl). Ver, por ejemplo, Coincidencia de patrones en el manual de Bash

Entonces, [[:space:]]es parte de una expresión regular o coincidencia de patrón, una que coincide solo con espacios en blanco.

Por ejemplo, una coincidencia de patrón (shell estándar, no específico de Bash):

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

o una expresión regular (Bash):

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

Tenga en cuenta que aunque las expresiones entre paréntesis [...]funcionan de la misma manera en expresiones regulares y patrones de shell, generalmente no son lo mismo. (case y [[ string == pattern ]]usa coincidencias de patrones, [[ string =~ regex ]]usa expresiones regulares).

Las expresiones regulares tampoco son específicas de shell, se usan en eg awky sedtambién, y se describen, por ejemplo, en la página de manual de Linuxregex(7)

ilkkachu
fuente