Làm thế nào để biểu thức dấu ngoặc đơn này trong grep hoạt động?


38

Tôi đã thấy một trong những lót gần đây:

$ ps -ef | grep [f]irefox 

thorsen   16730     1  1 Jun19 ?        00:27:27 /usr/lib/firefox/firefox ...

Vì vậy, nó dường như trả về danh sách các quy trình có "firefox" trong dữ liệu nhưng lại bỏ qua quy trình grep, và do đó có vẻ gần tương đương với:

ps -ef |grep -v grep| grep firefox

Tôi không thể hiểu làm thế nào nó hoạt động mặc dù. Tôi đã xem trang người đàn ông trên grep và những nơi khác nhưng không tìm thấy lời giải thích.

Và để kết hợp bí ẩn nếu tôi chạy:

$ ps -ef | grep firefox  > data
$ grep [f]irefox data

thorsen   15820 28618  0 07:28 pts/1    00:00:00 grep --color=auto firefox
thorsen   16730     1  1 Jun19 ?        00:27:45 /usr/lib/firefox/firefox ....

[t] rick dường như ngừng hoạt động!

Ai đó ở đây sẽ biết những gì đang xảy ra tôi chắc chắn.

Cảm ơn.


Hmm, bạn có chắc chắn rằng điều này là chính xác? ps -eaf | grep [fF] irefox sẽ có ý nghĩa hơn. Điều này trông giống như một biểu thức thông thường và có nghĩa là khớp với bất kỳ một trong các ký tự kèm theo. Cũng có thể được thực hiện dưới dạng phạm vi, ví dụ [0-9]
mbs

Vâng vâng. Đó là vấn đề tôi gặp phải: một lớp nhân vật chỉ chứa một nhân vật dường như vô nghĩa nhưng vẫn tạo ra hiệu ứng phụ "bí ẩn"! Dù sao jokerdino đã cung cấp một lời giải thích tốt.
Thorsen

Câu trả lời:


57

Biểu thức dấu ngoặc vuông là một phần của bash shell (và các shell khác) cũng khớp với mẫu lớp ký tự của grep.

Các grepchương trình theo mặc định hiểu POSIX biểu thức thông thường cơ bản. Với điều đó bạn có thể định nghĩa các lớp nhân vật. Ví dụ: ps -ef | grep [ab9]irefoxsẽ tìm " a irefox", " b irefox", " 9 irefox" nếu chúng tồn tại, nhưng không phải " ab irefox".

Lệnh grep [a-zA-Z0-9]irefoxthậm chí sẽ tìm thấy tất cả các quy trình bắt đầu bằng chính xác một chữ cái hoặc số và kết thúc bằng "irefox".

Vì vậy, ps -ef | grep firefoxtìm kiếm các dòng với firefoxnó. Vì quá trình grep tự nó có "firefox" trong đó, grep cũng tìm thấy điều đó. Bằng cách thêm a [], chúng tôi chỉ tìm kiếm lớp ký tự "[f]" (chỉ bao gồm chữ "f" và tương đương với chỉ một "f" không có dấu ngoặc). Ưu điểm của dấu ngoặc bây giờ là chuỗi "firefox" không còn xuất hiện trong lệnh grep. Do đó, grep sẽ không hiển thị trong kết quả grep.

Bởi vì không có nhiều người quen thuộc với dấu ngoặc vuông là khớp lớp nhân vật và các biểu thức chính quy nói chung, kết quả thứ hai có thể trông hơi bí ẩn.

Nếu bạn muốn sửa kết quả thứ hai, bạn có thể sử dụng chúng theo cách này:

ps -ef | grep [f]irefox  > data
grep firefox data

(Tài liệu tham khảo)


1
Hừm. Điều đó đã không xảy ra với tôi rằng [] là thứ được giải thích bởi lớp vỏ TRƯỚC KHI grep thậm chí sẽ có cơ hội. Cảm ơn đã giải thích. Tất cả [m] yteries đã giải quyết.
Thorsen

Vui vẻ giúp đỡ. Chúc một ngày tốt lành :)
jokerdino

1
Trong bash, dấu ngoặc vuông sẽ được chuyển đến grep nếu không có từ nào khớp với từ mà chúng nằm trong (tức là không có tệp nào có tên "firefox" trong thư mục hiện tại). Tuy nhiên, grep cũng có các lớp ký tự và [f] trong grep giống như f.
Daniel Hershcovich

6
Trên thực tế trong trường hợp này tôi không nghĩ nó được giải thích bởi shell trước grep. Tôi nghĩ [f]là khung biểu thức khớp biểu thức chính quy cho các lớp ký tự. Như trong "[a-z0-9] irefox" grep cũng sẽ khớp với "airefox" và "0irefox". Bạn có thể dễ dàng thấy rằng đó không phải là một bash tích hợp kể từ khi echo $([f])trả về một lỗi.
con-f-sử dụng

4
Lý do cụ thể [f]irefoxhoạt động cho mục đích này là nó không được mở rộng bởi vỏ. Khi shell mở rộng [f]irefoxra firefox, điều đó gây ra grepđể xem firefox, và sau đó firefoxlà một phần của grepchuỗi lệnh, chính xác như thể grep firefoxđược chạy. Nhưng thật tốt khi giữ mô hình shell phù hợp , đặc biệt là khi viết kịch bản, bởi vì nếu có một tệp được gọi firefoxtrong thư mục hiện tại , thì shell sẽ mở rộng [f]irefoxsangfirefox và phương thức này không thành công, tức là grepdòng từ psđược hiển thị.
Eliah Kagan

10

Lý do là chuỗi

grep firefox

phù hợp với mẫu firefox, nhưng chuỗi

grep [f]irefox

không khớp với mẫu [f]irefox(tương đương với mẫu firefox).

Đó là lý do tại sao grep đầu tiên khớp với dòng lệnh quy trình riêng của nó, trong khi grep thứ hai thì không.


Điều này làm cho đầu tôi đau hơn nữa
Pithikos
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.