grep và thoát khỏi một ký hiệu đô la


31

Tôi muốn biết tập tin nào có chuỗi $Id$.

grep \$Id\$  my_dir/mylist_of_files

trả về 0 lần xuất hiện.

Tôi phát hiện ra rằng tôi phải sử dụng

grep \$Id$ my_dir/mylist_of_files

Sau đó, tôi thấy rằng nó $Idđược tô màu trong đầu ra, tức là nó đã được khớp.

Làm thế nào tôi có thể phù hợp với thứ hai $và tại sao không \$Id\$hoạt động.

Không có vấn đề gì nếu $nhân vật thứ hai là nhân vật cuối cùng hay không.

Tôi sử dụng grep2.9.


Trước khi đăng câu hỏi của tôi, tôi đã sử dụng google ...

Tôi tìm thấy một câu trả lời

Để tìm kiếm $ (ký hiệu đô la) trong tệp có tên test2, hãy nhập:

grep \\ $ test2

Các ký tự \\ (dấu gạch chéo kép) là cần thiết để buộc shell chuyển \ \ (dấu gạch chéo đơn, ký hiệu đô la) cho lệnh grep. Ký tự \ (dấu gạch chéo ngược đơn) cho lệnh grep xử lý ký tự sau (trong ví dụ này là $) dưới dạng ký tự bằng chữ chứ không phải là ký tự biểu thức. Sử dụng lệnh fgrep để tránh sự cần thiết phải sử dụng các ký tự thoát như dấu gạch chéo ngược.

nhưng tôi không hiểu tại sao grep \$Idlàm việc và tại sao grep \\$Id\\$không.

Tôi có đôi chút hoang mang...

Câu trả lời:


25

Có 2 vấn đề riêng biệt ở đây.

  1. grepsử dụng Biểu thức chính quy cơ bản (BRE) và $là ký tự đặc biệt trong BRE chỉ ở cuối biểu thức. Hậu quả của việc này là 2 trường hợp $trong $Id$không bằng nhau. Người đầu tiên là một nhân vật bình thường và người thứ hai là một mỏ neo phù hợp với cuối dòng. Để biến $trận đấu thứ hai thành một nghĩa đen, $bạn sẽ phải gạch chéo lại thoát khỏi nó, tức là $Id\$. Thoát khỏi cái đầu tiên $cũng hoạt động: \$Id\$và tôi thích cái này vì nó có vẻ phù hợp hơn.¹

  2. Có hai cơ chế thoát / trích dẫn hoàn toàn không liên quan tại nơi làm việc ở đây: trích dẫn shell và trích dẫn dấu gạch chéo ngược. Vấn đề là nhiều ký tự mà các biểu thức thông thường sử dụng cũng đặc biệt đối với hệ vỏ, và trên hết là ký tự thoát regex, dấu gạch chéo ngược, cũng là một ký tự trích dẫn shell. Đây là lý do tại sao bạn thường thấy các mớ hỗn độn liên quan đến dấu gạch chéo kép, nhưng tôi không khuyên bạn nên sử dụng dấu gạch chéo ngược để trích dẫn các biểu thức thông thường vì nó không dễ đọc.

    Thay vào đó, cách đơn giản nhất để làm điều này là trước tiên đặt toàn bộ regex của bạn vào trong dấu ngoặc đơn như trong 'regex'. Trích dẫn duy nhất là hình thức trích dẫn shell mạnh nhất, miễn là regex của bạn không chứa các trích dẫn đơn, bạn không còn phải lo lắng về trích dẫn shell và có thể tập trung vào cú pháp BRE thuần túy.

Vì vậy, áp dụng điều này trở lại ví dụ ban đầu của bạn, hãy ném regex ( \$Id\$) chính xác vào trong dấu ngoặc đơn. Sau đây nên làm những gì bạn muốn:

grep '\$Id\$' my_dir/my_file

Lý do \$Id\$không hoạt động là vì sau khi loại bỏ trích dẫn shell (cách nói chính xác hơn về trích dẫn shell) được áp dụng, biểu thức chính quy grepnhìn thấy là $Id$. Như đã giải thích trong (1.), regex này chỉ khớp với một chữ $Idở cuối dòng bởi vì đầu tiên $là bằng chữ trong khi thứ hai là một ký tự neo đặc biệt.

Cũng lưu ý rằng nếu bạn từng chuyển sang Biểu thức chính quy mở rộng (ERE), ví dụ: nếu bạn quyết định sử dụng egrep(hoặc grep -E), $ký tự luôn đặc biệt. Trong ERE $Id$sẽ không bao giờ khớp với bất cứ điều gì vì bạn không thể có các ký tự sau khi kết thúc một dòng, vì vậy \$Id\$sẽ là cách duy nhất để đi.


3
Để tránh grep diễn giải tham số đầu tiên của nó như một biểu thức thông thường, bạn cũng có thể làm grep -F '$Id$'.
jfg956

Trong vỏ của tôi (bash 4.3.42) grep '$Id\$' ...grep \$Id\\$ ...làm việc
nitsas

2
Và nếu đây là một lệnh trong tệp thực hiện, bạn cũng phải thoát lệnh $có trước $: grep '$$Id\$$'. stackoverflow.com/a/2382810/2097284
Camille Goudeseune

-2

Để tìm kiếm $Id$trong một tập tin: bạn có thể sử dụng:grep '\$id*' filename


2
Điều đó sẽ phù hợp với bất cứ điều gì bắt đầu với $id, vì vậy, $ideaví dụ, không chỉ $id$.
terdon
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.