2012-05-10 33 views
9

Tôi gặp vấn đề với grep mà tôi không thể tìm ra. Tôi đang cố gắng để tìm kiếm tất cả các trường hợp của các từ trường hợp thấp hơn kèm theo trong dấu ngoặc kép (chuỗi C) trong một tập hợp các tập tin nguồn. Sử dụng bash và grep gnu:Mô hình Grep khớp với chuỗi chữ thường được đính kèm trong dấu ngoặc kép

grep -e '"[a-z]+"' *.cpp 

mang lại cho tôi không có trận đấu, trong khi

grep -e '"[a-z]*"' *.cpp 

mang lại cho tôi phù hợp như "Abc" mà không phải là chỉ thấp hơn nhân vật như vậy. Biểu thức chính quy thích hợp chỉ khớp với "abc" là gì?

+0

Regex thứ hai của bạn có vẻ ổn. Tôi đã thử nó và nó không phù hợp với các ký tự chữ hoa. – Misha

+1

@ Giống như bạn đang quên thứ tự đối chiếu địa phương cụ thể. –

+0

@Don Cảm ơn, thậm chí không nghĩ về điều đó! – Misha

Trả lời

8

Cậu quên để thoát khỏi ký tự meta.

grep -e '"[a-z]\+"' 

Đối với phần thứ hai, lý do khớp với ký tự nhiều chữ là do ngôn ngữ của bạn. Như sau:

$ echo '"Abc"' | grep -e '"[a-z]\+"' 
"Abc" 
$ export LC_ALL=C 
$ echo '"Abc"' | grep -e '"[a-z]\+"' 
$ 

Để có được hành vi "ascii-like", bạn cần phải thiết lập miền địa phương của bạn để "C", theo quy định tại các trang grep người đàn ông:

Trong một biểu thức khung, biểu thức phạm vi bao gồm hai ký tự được phân tách bằng dấu gạch ngang. Nó khớp với bất kỳ ký tự đơn nào mà sắp xếp giữa hai ký tự, bao gồm, bằng cách sử dụng chuỗi đối chiếu và bộ ký tự của miền địa phương. Ví dụ: trong ngôn ngữ C mặc định là , [a-d] tương đương với [abcd]. Nhiều miền địa phương sắp xếp các ký tự theo thứ tự từ điển và trong các ngôn ngữ này [a-d] là thường không tương đương với [abcd]; nó có thể tương đương với [aBbCcDd], chẳng hạn. Để có được cách diễn giải truyền thống của các biểu thức ngoặc đơn, bạn có thể sử dụng ngôn ngữ C bằng cách đặt biến môi trường LC_ALL thành giá trị C.

+0

Yup, ngôn ngữ ngu ngốc. Ngoài ra, tại sao tôi phải thoát khỏi +? Tôi sẽ nghĩ rằng nếu tôi muốn có một chữ + Tôi sẽ thoát khỏi nó và rằng một trần + sẽ được coi là metacharacter. –

+1

Trong các biểu thức chính quy cơ bản, các ký tự meta?, +, {, |, (, Và) mất đi ý nghĩa đặc biệt của chúng; thay vào đó hãy sử dụng các phiên bản bị gạch chéo \ ?, \ +, \ {, \ |, \ (và \). Để có được regexen mở rộng, hãy sử dụng -E –

+0

-E, cảm ơn. Thói quen cũ khó thay đổi. –

1

Mask +

grep -e '"[a-z]\+"' *.cpp 

hoặc sử dụng egrep:

egrep '"[a-z]+"' *.cpp 

có lẽ bạn đã -E trong tâm trí:

grep -E '"[a-z]+"' *.cpp 

Các -e chữ thường được sử dụng, ví dụ, để chỉ định nhiều mẫu tìm kiếm.

Các phaenomenon ký tự chữ hoa có nguồn gốc từ ngôn ngữ của bạn - mà bạn có thể ngăn với:

LC_ALL=C egrep '"[a-z]+"' *.cpp 
+0

Tôi nghĩ grep -e là egrep. Tôi đoán tôi đã nhầm. –

+0

Vâng, tôi cũng nghĩ như vậy, nhưng vì thói quen của tôi là sử dụng egrep, tôi đã kiểm tra egrep mà không cần nhìn gần hơn với tùy chọn -e, và ngay sau khi thành công với egrep, tôi nhận ra rằng -e nên làm một điều tương tự - tôi nghĩ như vậy. Nhưng tùy chọn đúng là -E, với vốn E. Vui lòng tra cứu trong trang manpage. –

0

Bạn có thể cần phải thoát khỏi +:

grep -e '"[a-z]\+"' *.cpp 
0

Nếu bạn không muốn gây nhầm lẫn với ngôn ngữ, điều này làm việc cho tôi:

grep -e '"[[:lower:]]\+"' 
Các vấn đề liên quan