Tôi muốn biết nếu một chuỗi $string
sẽ được khớp bởi một mẫu hình cầu $pattern
. $string
có thể hoặc không thể là tên của một tập tin hiện có. Tôi có thể làm cái này như thế nào?
Giả sử các định dạng sau cho chuỗi đầu vào của tôi:
string="/foo/bar"
pattern1="/foo/*"
pattern2="/foo/{bar,baz}"
Tôi muốn tìm một thành ngữ bash xác định nếu $string
có thể được kết hợp bởi $pattern1
, $pattern2
hoặc bất kỳ mẫu glob tùy ý khác. Đây là những gì tôi đã cố gắng cho đến nay:
[[ "$string" = $pattern ]]
Điều này gần như hoạt động, ngoại trừ
$pattern
được hiểu là một mẫu chuỗi và không phải là một mẫu toàn cầu.[ "$string" = $pattern ]
Vấn đề với cách tiếp cận này là
$pattern
được mở rộng và sau đó so sánh chuỗi được thực hiện giữa$string
và mở rộng$pattern
.[[ "$(find $pattern -print0 -maxdepth 0 2>/dev/null)" =~ "$string" ]]
Cái này hoạt động, nhưng chỉ khi
$string
chứa một tập tin tồn tại.[[ $string =~ $pattern ]]
Điều này không hoạt động vì
=~
toán tử gây ra$pattern
được hiểu là biểu thức chính quy mở rộng, không phải là mẫu hình cầu hoặc ký tự đại diện.
ls /foo/*
bây giờ bạn có thể khớp trong một
foo/{bar,baz}
thực sự là một mở rộng cú đúp (không phải là mở rộng tham số) trong khi foo/*
là mở rộng tên đường dẫn. $string
là mở rộng tham số. Tất cả đều được thực hiện tại các thời điểm khác nhau và theo các cơ chế khác nhau.
case
câu lệnh sẽ thực hiện Mở rộng tên đường dẫn ("globalbing") theo hướng dẫn Bash.
{bar,baz}
không phải là một mô hình. Đó là mở rộng tham số. Sự khác biệt tinh tế nhưng quan trọng trong đó{bar,baz}
được mở rộng từ rất sớm thành nhiều đối số,bar
vàbaz
.