Ý nghĩa của [[: space:]] trong bash là gì?


23

Tôi vừa đi qua một kịch bản bash. Điều gì có [[:space:]]nghĩa trong một kịch bản bash? Tại sao đại tràng đôi?

Câu trả lời:


35

Thực sự, nó là trong hướng dẫn bash, nhưng nó giúp biết những gì bạn đang tìm kiếm, điều này không hữu ích nếu bạn không biết bạn đang nhìn gì. Nếu bạn đã tìm kiếm, [[bạn sẽ bị phân tâm bởi [[ expression ]]phần biểu thức điều kiện. Ngoài ra, tìm kiếm :space:đất cho bạn trong hai ví dụ dưới cùng một phần. Bạn có thể theo dõi mẩu bánh mì trong ví dụ đó:

Ví dụ: dòng sau sẽ khớp với một dòng (được lưu trong dòng biến shell) nếu có một chuỗi các ký tự trong giá trị bao gồm bất kỳ số nào, bao gồm 0, các ký tự khoảng trắng, 0 hoặc một thể hiện của 'a', sau đó a 'B':

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

... Từ đó bạn có thể ghép lại với nhau rằng [[:space:]]phần tương ứng với "nhân vật không gian", nhưng bạn có thể được tha thứ vì nghĩ rằng đó chỉ là một nhân vật không gian theo nghĩa đen chứ không phải là cả một lớp nhân vật, đó là những gì nó thể hiện.

Nếu bạn (tình cờ?) Tìm kiếm chuỗi " space"(nghĩa là khoảng trắng theo sau từ "khoảng trắng") trong hướng dẫn bash trực tuyến , sẽ có "chỉ" khoảng 32 kết quả khớp. Khoảng một phần mười sẽ ở đây:

Trong '[' và ']', các lớp ký tự có thể được chỉ định bằng cú pháp [: class:], trong đó lớp là một trong các lớp sau được định nghĩa trong tiêu chuẩn POSIX:

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

Một lớp nhân vật phù hợp với bất kỳ nhân vật thuộc về lớp đó.

Sau đó sẽ đưa bạn đến tiêu chuẩn POSIX nơi bạn có thể tìm kiếm cụm từ "lớp nhân vật" và tìm

wctype, wctype_l - xác định lớp ký tự , sẽ đưa bạn đến tận:

Các hàm wctype () [CX] [Bắt đầu tùy chọn] và wctype_l () [Kết thúc tùy chọn] sẽ xác định các giá trị của wctype_t theo quy tắc của bộ ký tự được mã hóa được xác định bởi thông tin loại ký tự trong ngôn ngữ hiện tại [CX] [Bắt đầu tùy chọn] hoặc ở miền địa phương được đại diện bởi miền địa phương, [Kết thúc tùy chọn] tương ứng (loại LC_CTYPE).

Nếu sau đó bạn đã theo liên kết setlocale , cuối cùng bạn sẽ nhận được câu trả lời thực sự của mình, trong phần Địa điểm:

không gian

Xác định các ký tự được phân loại là các ký tự khoảng trắng. Trong miền địa phương POSIX, chính xác <space>, <form-feed>, <newline>, <carriage-return>, <tab>, and <vertical-tab>sẽ được bao gồm.

Trong tệp định nghĩa ngôn ngữ, không có ký tự nào được chỉ định cho các từ khóa trên, dưới, alpha, chữ số, biểu đồ hoặc xdigit sẽ được chỉ định. Bộ <space>, <form-feed>, <newline>, <carriage-return>, <tab>, and <vertical-tab>ký tự di động và bất kỳ ký tự nào có trong ô trống lớp sẽ tự động được bao gồm trong lớp này.


1
Dễ dàng tìm thấy khớp thủ công hơn LESS=+'/Within \[ and \],' man bashthay vì 32 nlệnh ext :-).
Isaac

5
@Isaac Tôi nghĩ vấn đề là dạy người đàn ông cách câu cá. Điều đó nói rằng, tôi không biết về less +"$cmd", vì vậy cảm ơn vì điều đó.
JoL

3
Thật vậy, tôi đã trả lời theo quan điểm của OP; họ có thể được tha thứ vì không nhận ra rằng bên ngoài []độc lập với bên trong []. Tôi đã cố gắng (!) Để tìm cách từ câu hỏi đến câu trả lời mà không biết quá nhiều về câu trả lời là gì, mặc dù phải mất một số phỏng đoán may mắn :)
Jeff Schaller

17

Nó không chỉ dành cho Bash, nó là một phần của ký hiệu POSIX.

POSIX là gì?

POSIX hoặc "Giao diện hệ điều hành di động cho uniX" là tập hợp các tiêu chuẩn xác định một số chức năng mà hệ điều hành (UNIX) nên hỗ trợ. Một trong những tiêu chuẩn này xác định hai hương vị của biểu thức chính quy.

Biểu thức khung POSIX

Biểu thức khung POSIX là một loại lớp ký tự đặc biệt. Biểu thức khung POSIX khớp một ký tự trong số các ký tự, giống như các lớp ký tự thông thường.

POSIX tiêu chuẩn

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

Không có tiêu chuẩn

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

cú pháp kế thừa (ai đó có thể tìm thấy tài liệu tham khảo cho những điều này?)

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

Bạn có thể tìm thêm thông tin ở đây: wiki


1
[[:ascii:]], Và [[:word:]]không phải là POSIX lớp (họ dường như được bashcụ thể), và tôi không thể tìm thấy [[:<:]]cũng không [[:>:]]một trong hai. Một tài liệu tham khảo tốt hơn có thể là pubs.opengroup.org/onlinepub/9699919799/basingefs/ Kẻ
Kusalananda

1
Vâng, [[:ascii:]][[:word:]]không có lớp POSIX tiêu chuẩn. cho [[:<:]][[:>:]], tôi không thể tìm thấy bất kỳ tài liệu tham khảo, nhưng nó là như nhau \b. vi.wikipedia.org/wiki/Regular_expression#Character_groupes
Nima


[[:<:]]cũng ở trong FreeBSD, với sự cảnh báo tương tự như PostgreSQL có: freebsd.org/cgi/
mẹo

1
[[:ascii:]][[:word:]]công việc khóa học trong Bash trong mô hình kết hợp, nhưng không phải trong biểu thức thông thường (ít nhất là trên hệ thống của tôi, tôi nghĩ rằng Bash sử dụng thư viện regex của hệ thống). Bah
ilkkachu

9

Trong các biểu thức thông thường và các mẫu ảm đạm / tên tệp, [...]cấu trúc khớp với bất kỳ một ký tự nào được liệt kê trong ngoặc. Trong các dấu ngoặc đó, một số lớp ký tự chuẩn được đặt tên có thể được sử dụng. Một trong số đó là [:space:], khớp với các ký tự khoảng trắng (như \strong biểu thức Perl). Xem ví dụ: Ghép mẫu trong sổ tay của Bash

Vì vậy, [[:space:]]là một phần của biểu thức hoặc biểu thức khớp thông thường, một phần chỉ khớp với khoảng trắng.

Ví dụ: khớp mẫu (vỏ tiêu chuẩn, không dành riêng cho Bash):

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

hoặc biểu thức chính quy (Bash):

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

Lưu ý rằng mặc dù các biểu thức ngoặc [...]hoạt động giống nhau trong các biểu thức và mẫu vỏ thông thường, nhưng nhìn chung chúng rất không giống nhau. ( case[[ string == pattern ]]sử dụng khớp mẫu, [[ string =~ regex ]]sử dụng biểu thức chính quy.)

Các biểu thức thông thường cũng không phải là đặc thù của shell, chúng được sử dụng trong ví dụ awksedquá, và được mô tả trong ví dụ trang man Linuxregex(7)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.