Kết hợp regex trong ksh


7

Tôi đang tìm cách làm một cái gì đó như thế này trong KSH:

if (( $var = (foo|bar)[0-9]*$ )); then
    print "variable matched regex"
fi

Có thể ở tất cả?

Đối với bản ghi tôi đang sử dụng Ksh Version M-11/16/88itrên máy Solaris 10.


4
Bạn có nhận ra biểu thức chính quy [foo|bar]có nghĩa là "khớp một ký tự từ tập hợp (a, b, f, o, r, |)" không? Nếu bạn có nghĩa là "khớp 'foo' hoặc 'bar'" bạn muốn(foo|bar)
glenn jackman

Đúng, không nhận thấy điều đó. Tôi sẽ cập nhật cho phù hợp.
rahmu

Câu trả lời:


8

Ksh có các biểu thức chính quy, nhưng không theo cú pháp thông thường (không có trong phiên bản trong Solaris 10 ).

if [[ $var = *@(foo|bar)*([0-9]) ]]; then 

Trong hướng dẫn sử dụng , hãy xem bên dưới các biểu thức có điều kiện của người dùng khác về những gì bên trong dấu ngoặc và bên dưới tên tập tin tạo ra tên tập tin hình chữ nhật.


Đây là một kết quả khớp mẫu, không phải là khớp biểu thức chính quy (sử dụng =~toán tử).
chepner

1
@chepner Nó không sử dụng cú pháp regex , nhưng nó là một biểu thức thông thường . Các mẫu Ksh bao gồm tất cả các toán tử biểu thức chính quy.
Gilles 'SO- ngừng trở nên xấu xa'

4

Sử dụng casevới các mẫu toàn cầu có thể làm việc cho bạn. Mẫu tổng hợp *(pattern-list)có nghĩa là "Khớp 0 hoặc nhiều lần xuất hiện của các mẫu đã cho" và @(pattern-list)có nghĩa là "Khớp chính xác một trong các mẫu đã cho".

matcher() {
  typeset var="$1"
  case "$var" in
    *@(foo|bar)*([0-9])) print "$var matched" ;;
    *) print "$var did not match" ;;
  esac
}

for var in foo bar baz foo123 abc_foo132 abc_foo123z bar1 1bar1 1bar1a; do 
  matcher "$var"
done

Đầu ra:

foo matched
bar matched
baz did not match
foo123 matched
abc_foo132 matched
abc_foo123z did not match
bar1 matched
1bar1 matched
1bar1a did not match

2

Tại sao không sử dụng egrep (1) ? Cung cấp cho bạn tất cả người dùng regex có thể mong muốn:

 if echo "$var" | egrep -s '(foo|bar)[0-9]*$'    # -s means "silent"
  then
    ...

Lưu ý bổ sung cho Solaris: Với Solaris, bạn có thể muốn kiểm tra manpage cho egrep - có phiên bản egrep được đặt tại /usr/xpg4/bin/egrepđó hỗ trợ thêm một số tùy chọn và khác về chức năng khi nói đến công cụ regex nâng cao.


1
đôi khi Solaris cũng sẽ cài đặt GNU Egrep, như gegrep. Hoặc từ CD Đồng hành, hoặc từ SunFreeWare, và thường là trong / opt / sfw / bin hoặc / usr / local / bin.
Tim Kennedy

@Tim: đúng, nhưng tôi không bao giờ dựa vào điều đó. Từ kinh nghiệm của tôi với các hệ thống sản xuất của khách hàng, bạn sẽ hiểu rõ hơn những gì HĐH cơ sở cung cấp vì những gì chúng tôi cho là tuyệt vời và hữu ích thường không được phép trong sản xuất. +1 dù sao ;-)
ktf

Đồng ý 100%. tôi cố gắng luôn luôn sử dụng các mô-đun script / chương trình / perl được cài đặt theo mặc định. giữ mọi thứ di động.
Tim Kennedy

1

Tôi đã làm một cái gì đó như thế này, sử dụng sed. Tôi không biết nó tốt như thế nào, nhưng ít nhất nó đã hoạt động ^^

if [ -z "$(echo "$var" | sed -e 's/(foo|bar)[0-9]*$//')" ]; then
    print "variable matched regex"
fi

Bạn cần đặt dấu ngoặc kép xung quanh các thay thế thay đổi, như mọi khi (nếu không, bạn sẽ nhận được kết quả sai hoặc lỗi trên một số đầu vào có chứa ký tự đại diện hoặc khoảng trắng). Ngay cả với trích dẫn đúng, điều này giả định rằng đầu vào không chứa một dòng mới. Hơn nữa, phương pháp của bạn rất phức tạp; greplà tự nhiên hơn , nhưng có một cách được xây dựng thành ksh .
Gilles 'SO- ngừng trở nên xấu xa'

0

Tôi biết tôi đến bữa tiệc muộn, nhưng thay vì giải pháp của ktf:

 if echo "$var" | egrep -s '(foo|bar)[0-9]*$'    # -s means "silent"
  then
    ...

bạn cũng có thể sử dụng

 if grep -q '(foo|bar)[0-9]*$' <<< "$var"        # -q means "quiet" ;-)
  then
    ...

Kỹ thuật này với <<<toán tử được gọi là herestring . Tuy nhiên, tôi cũng nên thêm một cảnh báo : điều này KHÔNG hoạt động trong môi trường chỉ đọc (nghĩa là bạn sẽ nhận được thông báo lỗi xấu stderr), vì việc trích dẫn này yêu cầu một tệp tạm thời được ghi vào một nơi nào đó. Theo như tôi biết, cách "cổ điển" với echovà một đường ống cũng sẽ hoạt động mà không có sự cho phép viết nào cả.

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.