Jakie jest znaczenie [[: space:]] w bash?

23

Właśnie natrafiłem na skrypt bash. Co [[:space:]]oznacza skrypt bash? Dlaczego podwójny dwukropek?

geraldin
źródło

Odpowiedzi:

35

Jest to rzeczywiście instrukcja obsługi bash, ale pomaga wiedzieć, czego szukasz, co nie jest pomocne, jeśli nie wiesz, na co patrzysz. Jeśli szukasz [[, rozprasza Cię [[ expression ]]sekcja wyrażeń warunkowych. Ponadto wyszukiwanie :space:wyląduje w dwóch przykładach w tej samej sekcji. W tym przykładzie możesz śledzić nawigację:

Na przykład, poniższe dopasuje linię (zapisaną w linii zmiennej powłoki), jeśli w wartości znajduje się ciąg znaków składający się z dowolnej liczby, w tym zero, spacji, zera lub jednego wystąpienia „a”, a następnie 'b':

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

... z którego można poskładać razem, że ta [[:space:]]część odpowiada „znakom spacji”, ale można wybaczyć, że myślała, że ​​jest to tylko dosłowny znak spacji, a nie cała klasa znaków, co reprezentuje.

Jeśli (zdarzyło Ci się?) Wyszukać ciąg znaków " space"(tj. Spację, po której następuje słowo „spacja”) w podręczniku bash online , istnieje „tylko” około 32 dopasowań do przejścia. O dziesiątej będzie tutaj:

W obrębie „[” i „]” klasy znaków można określić za pomocą składni [: class:], gdzie klasa jest jedną z następujących klas zdefiniowanych w standardzie POSIX:

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

Klasa znaków pasuje do dowolnego znaku należącego do tej klasy.

Który następnie zabrałby cię do standardu POSIX, gdzie możesz wyszukać termin „klasa znaków” i znaleźć

wctype, wctype_l - zdefiniuj klasę znaków , która doprowadzi cię do:

Funkcje wctype () [CX] [Opcja Start] i wctype_l () [Opcja Koniec] określają wartości wctype_t zgodnie z regułami zestawu znaków kodowanych zdefiniowanymi przez informacje o typie znaku w bieżących ustawieniach regionalnych [CX] [Opcja Start] lub w ustawieniach regionalnych reprezentowanych przez ustawienia regionalne, odpowiednio [Koniec opcji] (kategoria LC_CTYPE).

Jeśli następnie użyjesz linku setlocale , w końcu uzyskasz prawdziwą odpowiedź w sekcji Ustawienia regionalne :

przestrzeń

Zdefiniuj znaki, które będą klasyfikowane jako białe znaki. W ustawieniach regionalnych POSIX należy dokładnie <space>, <form-feed>, <newline>, <carriage-return>, <tab>, and <vertical-tab>uwzględnić.

W pliku definicji ustawień regionalnych nie należy podawać znaków dla słów kluczowych górna, dolna, alfa, cyfra, wykres lub xdigit. <space>, <form-feed>, <newline>, <carriage-return>, <tab>, and <vertical-tab>Przenośnego zestawu znaków, oraz wszelkich znaków zawartych w blankiecie klasy są automatycznie uwzględniane w tej klasie.

Jeff Schaller
źródło
1
Łatwiej jest znaleźć ręczne dopasowanie LESS=+'/Within \[ and \],' man bashzamiast 32 npoleceń ext :-).
Izaak
5
@Isaac Myślę, że chodzi o to, aby nauczyć tego człowieka, jak łowić ryby. To powiedziawszy, nie wiedziałem o less +"$cmd", więc dzięki za to.
JoL
3
Rzeczywiście odpowiedziałem, biorąc pod uwagę perspektywę PO; można im wybaczyć, że nie zauważyli, że to, co zewnętrzne, []jest niezależne od tego, co wewnętrzne []. Próbowałem (!) Znaleźć drogę od pytania do odpowiedzi, nie wiedząc zbyt wiele o odpowiedzi, choć zajęło to trochę zgadywania :)
Jeff Schaller
17

Nie dotyczy tylko Bash, jest częścią notacji POSIX.

Co to jest POSIX?

POSIX lub „Przenośny interfejs systemu operacyjnego dla uniX” to zbiór standardów, które definiują niektóre funkcje, które powinien obsługiwać system operacyjny (UNIX). Jeden z tych standardów definiuje dwa smaki wyrażeń regularnych.

Wyrażenia w nawiasach POSIX

Wyrażenia w nawiasach POSIX to specjalny rodzaj klas znaków. Wyrażenia w nawiasach POSIX pasują do jednego znaku z zestawu znaków, podobnie jak zwykłe klasy znaków.

Standardowy 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

Brak standardów

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

starsza składnia (czy ktoś może znaleźć odniesienie do nich?)

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

Więcej informacji można znaleźć tutaj: wiki

Nima
źródło
1
[[:ascii:]], i [[:word:]]nie są klasami POSIX (wydają się być bashspecyficzne), i nie mogę znaleźć [[:<:]]ani [[:>:]]jednego, ani drugiego. Lepszym odniesieniem może być pubs.opengroup.org/onlinepubs/9699919799/basedefs/…
Kusalananda
1
Tak, [[:ascii:]]i [[:word:]]nie są żadnymi standardowymi klasami POSIX. na [[:<:]]i [[:>:]]nie mogę znaleźć żadnych odniesień, ale jest to samo \b. en.wikipedia.org/wiki/Regular_expression#Character_classes
Nima
Postgres określa użycie [[:<:]]i twierdzi, że: Jest to rozszerzenie zgodne z POSIX 1003.2, ale nieokreślone
Isaac
[[:<:]]jest również w FreeBSD, z tym samym zastrzeżeniem co PostgreSQL: freebsd.org/cgi/…
ilkkachu
1
A [[:ascii:]]i [[:word:]]oczywiście pracy w bash w dopasowywania wzorców, ale nie w wyrażeniach regularnych (przynajmniej w moim systemie, myślę Bash używa regex biblioteki systemu). Bah.
ilkkachu
9

W wyrażeniach regularnych i globach nazw plików / wzorcach powłok [...]konstrukcja konstruuje dowolny znak z tych wymienionych w nawiasach. W tych nawiasach można użyć wielu nazwanych standardowych klas znaków . Jednym z nich jest [:space:]dopasowanie znaków białych znaków (jak \sw wyrażeniach regularnych Perla). Zobacz np. Dopasowywanie wzorców w instrukcji Basha

Jest więc [[:space:]]częścią wyrażenia regularnego lub dopasowania do wzorca, które pasuje tylko do białych znaków.

Np. Dopasowanie wzorca (standardowa powłoka, nie specyficzna dla Bash):

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

lub regex (Bash):

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

Należy pamiętać, że mimo wyrażenia wspornik [...]działają tak samo w wyrażeniach regularnych i Shell wzory, są one na ogół bardzo dużo nie to samo. ( casei [[ string == pattern ]]używaj dopasowania wzorca, [[ string =~ regex ]]używa wyrażeń regularnych).

Wyrażenia regularne również nie są specyficzne dla powłoki, są używane np. awkI sedteż i są opisane np. Na stronie podręcznika systemu Linuxregex(7)

ilkkachu
źródło