bash
ban đầu được thiết kế vào cuối những năm 80 như là một bản sao một phần ksh
với một số tính năng tương tác từ csh / tcsh.
Nguồn gốc của Globing phải được tìm thấy trong những chiếc vỏ trước đó mà nó tạo ra.
ksh
chính nó là một phần mở rộng của vỏ Bourne. Bản thân vỏ Bourne (phát hành lần đầu tiên vào năm 1979 trong Unix V7) là một bản triển khai rõ ràng từ đầu, nhưng nó không hoàn toàn rời khỏi vỏ Thompson (vỏ của V1 -> V6) và các tính năng kết hợp từ vỏ Mashey.
Cụ thể, các đối số lệnh vẫn được phân tách bằng khoảng trắng, |
giờ là toán tử đường ống mới nhưng ^
vẫn được hỗ trợ như một giải pháp thay thế (và cũng giải thích lý do tại sao bạn làm [!a-z]
và không [^a-z]
), $1
vẫn là đối số đầu tiên cho tập lệnh và dấu gạch chéo ngược vẫn là ký tự thoát . Vì vậy, nhiều toán tử regrec ( ^\|$
) có ý nghĩa đặc biệt của riêng chúng trong shell.
Vỏ của Thompson dựa vào một tiện ích bên ngoài để đánh bóng. Khi sh
tìm thấy không được trích dẫn *
, [
hoặc ?
s trong lệnh, nó sẽ chạy lệnh thông qua glob
.
rm *.txt
cuối cùng sẽ chạy toàn cầu như:
["glob", "rm", "*.txt"]
và global sẽ kết thúc rm
với danh sách các tệp khớp với mẫu đó.
grep a.\*b *.txt
sẽ chạy glob
như:
["glob", "grep", "a.\252b", "*.txt"]
Ở *
trên đã được trích dẫn bằng cách đặt bit thứ 8 cho ký tự đó, ngăn glob
không cho nó là ký tự đại diện. glob
sau đó sẽ loại bỏ bit đó trước khi gọi grep
.
Để làm tương đương với regexps, đó sẽ là:
regexp rm '\.txt$'
Hoặc là:
regexp rm '^[^.].*\.txt$'
để loại trừ các tập tin dấu chấm.
Sự cần thiết phải thoát khỏi các toán tử khi chúng nhân đôi các ký tự đặc biệt, thực tế là .
, phổ biến trong tên tệp là một toán tử regrec làm cho nó không phù hợp lắm với các tên tệp và phức tạp cho người mới bắt đầu. Trong hầu hết các trường hợp, tất cả những gì bạn cần là các ký tự đại diện có thể thay thế một ( ?
) hoặc bất kỳ số ( *
) ký tự nào.
Bây giờ, các shell khác nhau đã thêm các toán tử Globing khác nhau. Ngày nay, các khối ksh và zsh (và ở một mức độ nào bash -O extglob
đó thực hiện một tập hợp con của các khối ksh) có chức năng tương đương với các biểu thức chính quy với một cú pháp ít cồng kềnh hơn để sử dụng với tên tệp và cú pháp shell hiện tại. Chẳng hạn, trong zsh
(với phần mở rộng được mở rộng), bạn có thể làm:
echo a#.txt
nếu bạn muốn (không chắc) khớp với tên tệp bao gồm các chuỗi a
theo sau .txt
. Dễ dàng hơn echo (^a*\.txt$)
(ở đây sử dụng dấu ngoặc nhọn như một cách để cô lập các toán tử regex khỏi các toán tử shell có thể là một cách mà shell có thể đối phó với nó).
echo (foo|bar|<1-20>).(#i)mpg
Đối với các tệp mpg (không phân biệt chữ hoa chữ thường) có tên cơ sở là foo, bar hoặc số thập phân từ 1 đến 20 ...
ksh93
bây giờ cũng có thể kết hợp regexps (cơ bản, mở rộng, giống như perl hoặc "tăng cường") trong các khối của nó (mặc dù nó khá lỗi) và thậm chí cung cấp một công cụ để chuyển đổi giữa global và regrec ( printf %R
, printf %P
):
echo ~(Ei:.*\.txt)
để khớp các tệp txt (không bị ẩn) với các biểu thức chính quy E xtends, case- i nsensitively.
rm -- ^[^.].*\.txt$
thay vìrm -- *.txt
?