Was bedeutet [[: space:]] in bash?

23

Ich bin gerade auf ein Bash-Skript gestoßen. Was [[:space:]]bedeutet in einem Bash-Skript? Warum der Doppelpunkt?

Geraldin
quelle

Antworten:

35

Es steht zwar im Bash-Handbuch, aber es hilft zu wissen, wonach Sie suchen. Dies ist nicht hilfreich, wenn Sie nicht wissen, wonach Sie suchen. Wenn Sie nach suchen, werden [[Sie durch den [[ expression ]]Abschnitt für bedingte Ausdrücke abgelenkt . Darüber hinaus finden :space:Sie in zwei Beispielen im selben Abschnitt die Suche nach Ländern. Sie können der Brotkrume in diesem Beispiel folgen:

Das Folgende passt beispielsweise zu einer Zeile (in der Shell-Variablenzeile gespeichert), wenn der Wert eine Folge von Zeichen enthält, die aus einer beliebigen Zahl, einschließlich Null, Leerzeichen, Null oder einer Instanz von 'a' und dann a besteht 'b':

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

... aus dem man zusammensetzen konnte, dass der [[:space:]]Teil "Leerzeichen" entsprach, aber man konnte sich verzeihen, dass es sich nur um ein buchstäbliches Leerzeichen und nicht um eine ganze Klasse von Zeichen handelte, für die es steht.

Wenn Sie (zufällig?) " space"Im Online-Bash-Handbuch nach der Zeichenfolge (dh einem Leerzeichen, gefolgt vom Wort "Leerzeichen" ) suchen , müssen "nur" etwa 32 Übereinstimmungen ausgeführt werden. Ungefähr der zehnte wird hier sein:

Innerhalb von '[' und ']' können Zeichenklassen mit der Syntax [: class:] angegeben werden, wobei class eine der folgenden im POSIX-Standard definierten Klassen ist:

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

Eine Zeichenklasse entspricht jedem Zeichen, das zu dieser Klasse gehört.

Was würde Sie dann zum POSIX-Standard bringen, wo Sie nach dem Begriff "Zeichenklasse" suchen und finden könnten

wctype, wctype_l - Definiert die Zeichenklasse , mit der Sie Folgendes erreichen :

Die Funktionen wctype () [CX] [Option Start] und wctype_l () [Option End] bestimmen die Werte von wctype_t gemäß den Regeln des codierten Zeichensatzes, der durch die Zeichentypinformationen im aktuellen Gebietsschema [CX] [Option Start] definiert ist. oder in dem Gebietsschema, das durch das Gebietsschema dargestellt wird, jeweils [Option End] (Kategorie LC_CTYPE).

Wenn Sie dann den gefolgt setlocaleQ Link, würden Sie schließlich Ihre wirkliche Antwort bekommen, in dem Abschnitt Locale :

Platz

Definieren Sie Zeichen, die als Leerzeichen klassifiziert werden sollen. Im POSIX-Gebietsschema muss genau angegeben <space>, <form-feed>, <newline>, <carriage-return>, <tab>, and <vertical-tab>werden.

In einer Gebietsschemadefinitionsdatei darf kein Zeichen für die Schlüsselwörter "Upper", "Lower", "Alpha", "Digit", "Graph" oder "XDIGIT" angegeben werden. Die <space>, <form-feed>, <newline>, <carriage-return>, <tab>, and <vertical-tab>Zeichen des portablen Zeichensatzes und alle im Klassenleerzeichen enthaltenen Zeichen werden automatisch in diese Klasse aufgenommen.

Jeff Schaller
quelle
1
Einfacher, die manuelle Übereinstimmung mit LESS=+'/Within \[ and \],' man bashanstelle von 32 next-Befehlen zu finden :-).
Isaac
5
@Isaac Ich denke, es geht darum, dem Mann das Fischen beizubringen. Davon wusste ich nichts less +"$cmd", also danke dafür.
JoL
3
In der Tat antwortete ich aus der Perspektive des OP; Man könnte ihnen vergeben, wenn sie nicht erkennen, dass das Äußere []vom Inneren unabhängig ist []. Ich habe versucht , einen Weg aus der Frage auf die Antwort zu finden , ohne zu wissen (!) Zu viel über das, was war die Antwort, obwohl es einige Glück Erraten :) nahm
Jeff Schaller
17

Es ist nicht nur für Bash, es ist Teil der POSIX-Notation.

Was ist POSIX?

POSIX oder "Portable Operating System Interface for uniX" ist eine Sammlung von Standards, die einige der Funktionen definieren, die ein (UNIX-) Betriebssystem unterstützen sollte. Einer dieser Standards definiert zwei Varianten von regulären Ausdrücken.

POSIX-Klammerausdrücke

POSIX-Klammerausdrücke sind eine besondere Art von Zeichenklassen. POSIX-Klammerausdrücke stimmen genau wie normale Zeichenklassen mit einem Zeichen aus einer Reihe von Zeichen überein.

Standard 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

Keine Standards

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

Legacy-Syntax (kann jemand auf diese verweisen?)

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

Weitere Informationen finden Sie hier: Wiki

Nima
quelle
1
[[:ascii:]]Und [[:word:]]ist nicht POSIX - Klassen (sie zu sein scheint bash-spezifische), und ich kann nicht finden , [[:<:]]noch [[:>:]]nicht. Eine bessere Referenz könnte pubs.opengroup.org/onlinepubs/9699919799/basedefs/…
Kusalananda
1
Ja, [[:ascii:]]und das [[:word:]]sind keine POSIX-Standardklassen. Für [[:<:]]und [[:>:]]kann ich keine Referenzen finden, aber es ist das gleiche \b. en.wikipedia.org/wiki/Regular_expression#Character_classes
Nima
Postgres definiert die Verwendung von [[:<:]]und behauptet, dass: Dies eine Erweiterung ist, die mit POSIX 1003.2
Isaac,
[[:<:]]ist auch in FreeBSD mit dem gleichen Vorbehalt wie PostgreSQL: freebsd.org/cgi/…
ilkkachu
1
Und [[:ascii:]]und [[:word:]]natürlich Arbeit in Bash in Pattern - Matching, aber nicht in regulären Ausdrücken (zumindest auf meinem System, ich denke , Bash das regex Bibliothek System verwendet). Bah.
Ilkkachu
9

In regulären Ausdrücken und Globs / Shell-Mustern für Dateinamen stimmt das [...]Konstrukt mit einem beliebigen Zeichen der in Klammern aufgeführten Zeichen überein. Innerhalb dieser Klammern, eine Reihe von Namen Standard - Zeichenzeichenklassen verwendet werden. Eines davon ist [:space:], das mit Leerzeichen übereinstimmt (wie \sin Perl-Regexen). Siehe zB Pattern Matching in Bashs Handbuch

Ist [[:space:]]also ein Teil eines regulären Ausdrucks oder einer Musterübereinstimmung, die nur mit Leerzeichen übereinstimmt.

ZB eine Musterübereinstimmung (Standard-Shell, nicht Bash-spezifisch):

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

oder ein Regex (Bash):

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

Beachten Sie, dass obwohl Klammerausdrücke [...]gleich in regulären Ausdrücken und Shell - Muster arbeiten, sie sind in der Regel sehr viel nicht gleich. ( caseund verwende Musterübereinstimmungen [[ string == pattern ]], [[ string =~ regex ]]verwende Regexes.)

Reguläre Ausdrücke sind auch nicht shellspezifisch, sie werden zB auch in awkund verwendet sedund sind zB in der Linux-Manpage beschriebenregex(7)

ilkkachu
quelle