Quelle est la signification de [[: space:]] en bash?

23

Je viens de tomber sur un script bash. Que [[:space:]]signifie un script bash? Pourquoi le double colon?

géraldine
la source

Réponses:

35

C'est, en effet, dans le manuel bash, mais cela aide à savoir ce que vous cherchez, ce qui n'est pas utile si vous ne savez pas ce que vous regardez. Si vous recherchiez, [[vous seriez distrait par la [[ expression ]]section des expressions conditionnelles. De plus, la recherche de :space:terrains vous donne deux exemples dans la même section. Vous pouvez suivre le fil d'Ariane dans cet exemple:

Par exemple, ce qui suit correspondra à une ligne (stockée dans la ligne de variable shell) s'il y a une séquence de caractères dans la valeur consistant en n'importe quel nombre, y compris zéro, des caractères d'espace, zéro ou une instance de 'a', puis un «b»:

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

... à partir duquel vous pourriez reconstituer que la [[:space:]]partie correspondait à des "caractères spatiaux", mais vous pourriez être pardonné de penser que ce n'était qu'un caractère spatial littéral et non une classe entière de caractères, ce qu'elle représente.

Si vous (par hasard?) Recherchez la chaîne " space"(c'est-à-dire un espace suivi du mot "espace") dans le manuel bash en ligne , il n'y a "que" environ 32 correspondances à parcourir. Le dixième sera ici:

Dans '[' et ']', les classes de caractères peuvent être spécifiées en utilisant la syntaxe [: class:], où class est l'une des classes suivantes définies dans la norme POSIX:

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

Une classe de caractères correspond à tout caractère appartenant à cette classe.

Ce qui vous amènerait ensuite au standard POSIX où vous pourriez rechercher le terme "classe de caractères" et trouver

wctype, wctype_l - définit la classe de caractères , qui vous amène jusqu'à:

Les fonctions wctype () [CX] [Option Start] et wctype_l () [Option End] doivent déterminer les valeurs de wctype_t selon les règles du jeu de caractères codés définies par les informations de type de caractère dans les paramètres régionaux actuels [CX] [Option Start] ou dans les paramètres régionaux représentés par les paramètres régionaux, respectivement [Option End] (catégorie LC_CTYPE).

Si vous suiviez ensuite le lien setlocale , vous obtiendriez enfin votre vraie réponse, dans la section Paramètres régionaux :

espace

Définissez les caractères à classer comme caractères d'espacement. Dans l'environnement local POSIX, exactement <space>, <form-feed>, <newline>, <carriage-return>, <tab>, and <vertical-tab>doit être inclus.

Dans un fichier de définition de paramètres régionaux, aucun caractère spécifié pour les mots clés supérieur, inférieur, alpha, chiffre, graphique ou xdigit ne doit être spécifié. Le jeu <space>, <form-feed>, <newline>, <carriage-return>, <tab>, and <vertical-tab>de caractères portable et tous les caractères inclus dans le blanc de classe sont automatiquement inclus dans cette classe.

Jeff Schaller
la source
1
Plus facile de trouver la correspondance manuelle avec LESS=+'/Within \[ and \],' man bashau lieu de 32 ncommandes ext :-).
Isaac
5
@Isaac Je pense que le but est d'apprendre à l'homme à pêcher. Cela dit, je ne savais pas less +"$cmd", alors merci pour cela.
JoL
3
En effet, j'ai répondu étant donné la perspective du PO; on pourrait leur pardonner de ne pas avoir compris que l'extérieur []est indépendant de l'intérieur []. J'ai essayé (!) De trouver un moyen de passer de la question à la réponse sans trop savoir quelle était la réponse, même s'il a fallu un peu de chance pour deviner :)
Jeff Schaller
17

Ce n'est pas seulement pour Bash, cela fait partie de la notation POSIX.

Qu'est-ce que POSIX?

POSIX ou "Interface du système d'exploitation portable pour uniX" est un ensemble de normes qui définissent certaines des fonctionnalités qu'un système d'exploitation (UNIX) doit prendre en charge. L'une de ces normes définit deux variantes d'expressions régulières.

Expressions du support POSIX

Les expressions entre crochets POSIX sont un type spécial de classes de caractères. Les expressions de support POSIX correspondent à un caractère sur un ensemble de caractères, tout comme les classes de caractères normales.

POSIX standard

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

Aucune Normes

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

syntaxe héritée (quelqu'un peut-il y trouver une référence?)

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

Vous pouvez trouver plus d'informations ici: wiki

Nima
la source
1
[[:ascii:]], et [[:word:]]ne sont pas des classes POSIX (elles semblent être bashspécifiques), et je ne peux pas trouver [[:<:]]non [[:>:]]plus. Une meilleure référence peut avoir été pubs.opengroup.org/onlinepubs/9699919799/basedefs/…
Kusalananda
1
Oui, [[:ascii:]]et il [[:word:]]n'y a pas de classes POSIX standard. pour [[:<:]]et [[:>:]], je ne trouve aucune référence, mais c'est la même chose \b. en.wikipedia.org/wiki/Regular_expression#Character_classes
Nima
Postgres définit l'utilisation [[:<:]]et affirme que: Il s'agit d'une extension compatible avec mais non spécifiée par POSIX 1003.2
Isaac
[[:<:]]est également dans FreeBSD, avec la même mise en garde que PostgreSQL: freebsd.org/cgi/…
ilkkachu
1
Et [[:ascii:]]et [[:word:]]des travaux de cours en Bash en correspondance de motif, mais pas dans les expressions régulières (au moins sur mon système, je pense que Bash utilise la bibliothèque regex du système). Bah.
ilkkachu
9

Dans les expressions régulières et les modèles globs / shell de nom de fichier, la [...]construction correspond à n'importe quel caractère de ceux répertoriés entre crochets. Dans ces crochets, un certain nombre de classes de caractères de caractères standard nommées peuvent être utilisées. L'un d'eux est celui [:space:]qui correspond aux caractères d' \sespacement (comme dans les expressions rationnelles Perl). Voir par exemple Pattern Matching dans le manuel de Bash

Donc, [[:space:]]fait partie d'une expression régulière ou d'une correspondance de modèle, qui correspond uniquement aux espaces blancs.

Par exemple, une correspondance de modèle (shell standard, non spécifique à Bash):

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

ou une expression régulière (Bash):

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

Notez que même si les expressions entre crochets [...]fonctionnent de la même dans les expressions régulières et des motifs shell, ils sont généralement très pas la même chose. ( caseet [[ string == pattern ]]utiliser des correspondances de motifs, [[ string =~ regex ]]utilise des expressions rationnelles.)

Les expressions régulières ne sont pas non plus spécifiques au shell, elles sont utilisées par exemple awket sedaussi, et sont décrites par exemple dans la page de manuel Linuxregex(7)

ilkkachu
la source