Grep không phải là một biểu thức chính quy


96

Tôi cần tìm kiếm một biến PHP $someVar. Tuy nhiên, Grep nghĩ rằng tôi đang cố chạy một regex và phàn nàn:

$ grep -ir "Something Here" * | grep $someVar
Usage: grep [OPTION]... PATTERN [FILE]...
Try `grep --help' for more information.
$ grep -ir "Something Here" * | grep "$someVar"
<<Here it returns all rows with "someVar", not only those with "$someVar">>

Tôi không thấy tùy chọn để yêu cầu grep không giải thích chuỗi dưới dạng regex, mà chỉ bao gồm $một ký tự chuỗi khác.


3
Trong câu hỏi này, vấn đề chính không nằm ở việc grepdiễn giải $như một regex. Đó là về việc thay thế shell bằng $someVargiá trị của biến môi trường someVar, có thể là chuỗi rỗng. Ví dụ thứ hai không nên trả về tất cả các hàng someVartrừ tất cả các dòng, bởi vì chuỗi trống nằm trong tất cả các dòng. Để nói với vỏ không thay thế, bạn phải sử dụng '$someVar'hoặc \$someVar. Sau đó, bạn sẽ phải đối phó với việc grepgiải thích $nhân vật.
Christophe Drevet-Droguet

1
@ ChristopheDrevet-Droguet: Cảm ơn bạn đã giải thích, tôi đã rất bối rối về việc downvote! Nhận xét của bạn đủ thông tin để trở thành một câu trả lời, trên thực tế, nó sẽ là một trong những câu trả lời tốt hơn trên trang nếu vậy.
dotancohen

Câu trả lời:



298

Sử dụng fgrep(không được dùng nữa) grep -Fhoặcgrep --fixed-strings , để làm cho nó coi mẫu như một danh sách các chuỗi cố định, thay vì regex.

Để tham khảo, tài liệu đề cập (phần trích):

-F --fixed-stringsDiễn giải mẫu dưới dạng danh sách các chuỗi cố định (thay vì biểu thức chính quy), được phân tách bằng các dòng mới, bất kỳ chuỗi nào trong số đó sẽ được so khớp. (-F được chỉ định bởi POSIX.)

fgrepgiống như grep -F. Lệnh gọi trực tiếp dưới dạng fgrep không được dùng nữa, nhưng được cung cấp để cho phép các ứng dụng lịch sử dựa vào chúng để chạy mà không bị sửa đổi.

Để tham khảo đầy đủ, hãy kiểm tra: https://www.gnu.org/savannah-checkouts/gnu/grep/manual/grep.html


câu trả lời đơn giản tuyệt vời.
breadmj

Đồng ý — khi bạn đang sử dụng các biến, bạn không thể làm điều gì đó giống như PHP addslashes()với nó trong bash. Đây là cách đơn giản nhất để làm điều đó.
geerlingguy

1
Cảm ơn bạn, điều này đã làm việc. Nhắc nhở: nếu sử dụng dấu ngoặc kép, bạn sẽ vẫn phải thoát khỏi$ , ví dụ grep -FR "unset(\$foo['bar'])"
:,

57

grep -Flà một cách chuẩn grepđể hiểu đối số là một chuỗi cố định, không phải một mẫu.


1
Nghiêm túc mà nói, đây đáng lẽ phải là câu trả lời được chấp nhận!
ankush981,

Câu trả lời hay đấy. Nó đã giải quyết vấn đề của tôi khi tôi tìm kiếm một chuỗi với $ bằng lệnh ssh. Thoát bằng "\" không hoạt động trong trường hợp đó. Nhưng cờ -F đã làm được điều đó.
Rajasekhar

8

Bạn phải nói với grep rằng bạn sử dụng một chuỗi cố định, thay vì một mẫu, sử dụng '-F':

grep -ir "Something Here" * | grep -F \$somevar

3

Trong câu hỏi này, vấn đề chính không nằm ở việc grepdiễn giải $như một regex. Đó là về việc thay thế shell bằng $someVargiá trị của biến môi trườngsomeVar , có thể là chuỗi rỗng.

Vì vậy, trong ví dụ đầu tiên, nó giống như gọi grepmà không có bất kỳ đối số nào, và đó là lý do tại sao nó cung cấp cho bạn một usageđầu ra. Ví dụ thứ hai không nên trả về tất cả các hàng có chứa someVartrừ tất cả các dòng, vì chuỗi rỗng nằm trong tất cả các dòng.

Để nói với vỏ không thay thế, bạn phải sử dụng '$someVar'hoặc \$someVar. Sau đó, bạn sẽ phải đối phó với việc giải thích $nhân vật theo kiểu grep , do đó có grep -Ftùy chọn được đưa ra trong nhiều câu trả lời khác.

Vì vậy, một câu trả lời hợp lệ sẽ là:

grep -ir "Something Here" * | grep '$someVar'

2

+1 cho -Ftùy chọn, nó sẽ là câu trả lời được chấp nhận. Ngoài ra, tôi đã có một hành vi "lạ" khi tìm kiếm -I..mẫu trong tệp của mình, vì nó -Iđược coi là một tùy chọn của grep; Để tránh những lỗi như vậy, chúng ta có thể chỉ định rõ ràng phần cuối của các đối số của lệnh bằng cách sử dụng --.

Thí dụ:

grep -HnrF -- <pattern> <files>

Hy vọng rằng sẽ giúp một ai đó.


F là viết tắt của cái gì?
Arnold Roa

Từ gnu.org/software/grep/manual/grep.html : "-F: Diễn giải mẫu dưới dạng danh sách các chuỗi cố định (thay vì biểu thức chính quy), được phân tách bằng các dòng mới, bất kỳ chuỗi nào trong số đó sẽ được khớp. (-F được chỉ định bởi POSIX.) "
Aloïké Go

Nếu --được sử dụng, có thể -HnrFđược bỏ qua?
Daniel

@Daniel Nó phụ thuộc vào những gì bạn muốn làm: -Ftránh diễn giải mẫu dưới dạng biểu thức chính quy, trong khi --tránh diễn giải các phần tử theo sau nó dưới dạng các tùy chọn của grep.
Aloïké Go

@ AloïkéGo Cảm ơn, tôi hiểu rồi.
Daniel
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.