Làm thế nào để grep vào mã nguồn mà không bắt bình luận


10

Tôi tìm kiếm một cách để grep trên mã nguồn mà đôi khi không có kết quả dương tính vì nhận xét. Chẳng hạn, nếu tôi tìm kiếm trên foo trên mã nguồn .c này:

/* 
 * foo has changed [...] and is now a 2-parameters function
 */
// foo(24)
foo(42, 28);

Một người ngây thơ grepsẽ tìm thấy 3 lần mà tôi chỉ muốn một lần. Tôi đã thấy cách này để làm điều đó trên StackOverflow, nhưng nó không đáp ứng nhu cầu của tôi: PHP không có sẵn trên nền tảng. Tôi cũng đã tìm thấy cách này để lấy ý kiến một dòng, nhưng nó chỉ giải quyết một phần của vấn đề của tôi.

Tôi cần sử dụng các công cụ kịch bản cổ điển (awk, sed, bash, grep, v.v.) và tôi cần nó phải nhanh ngay cả khi có hàng ngàn tệp.

Bạn có bây giờ nếu và làm thế nào có thể grep trên mã nguồn và chỉ mã nguồn?


3
Xây dựng bảng thẻ có thể là một cách tiếp cận tốt hơn, tùy thuộc vào những gì bạn đang làm.
Gilles 'SO- ngừng trở nên xấu xa'

Câu trả lời:


10

Bạn có thể thử một cách tiếp cận ngây thơ để phù hợp với những người không bình luận như thế này:

 $ egrep -v "^(//|/\*| \*)" sourcecode

Điều này sẽ phù hợp với chỉ nghịch chống lại các comments phía sau - đó là những dòng bắt đầu với một trong hai //, /*, *hoặc */- và do đó nó sẽ không bỏ qua khối được nhận xét ra với /**/cặp.


Được sửa đổi một chút để làm việc cho các nhận xét thụt lề: $ egrep -v "^ [[: space:]] * ((// | / * | *)" sourcecode
mbonness 20/11/19

11

grep hoạt động trên văn bản thuần túy và không biết gì về cú pháp cơ bản của chương trình C của bạn. Do đó, để không tìm kiếm bên trong các bình luận, bạn có một số tùy chọn:

  1. Xóa các nhận xét C trước khi tìm kiếm, bạn có thể thực hiện việc này bằng cách sử dụng gcc -fpreprocessed -dD -E yourfile.cĐể biết chi tiết, vui lòng xem /programming/2394017/remove-comments-from-cc-code

  2. Viết / sử dụng một số tập lệnh hoạt động nửa vời như bạn đã tìm thấy (ví dụ: chúng hoạt động bằng cách bỏ qua các dòng bắt đầu bằng //hoặc /*) để xử lý các chi tiết của tất cả các nhận xét C / C ++ có thể (một lần nữa, xem liên kết trước để biết một số testcase đáng sợ) . Sau đó, bạn vẫn có thể có dương tính giả, nhưng bạn không phải xử lý trước bất cứ điều gì.

  3. Sử dụng các công cụ nâng cao hơn để thực hiện "tìm kiếm ngữ nghĩa" trong mã. Tôi đã tìm thấy "coccigrep": http://home.regit.org/software/coccigrep/ Loại công cụ này cho phép tìm kiếm một số câu lệnh ngôn ngữ cụ thể (ví dụ: cập nhật cấu trúc với tên đã cho) và chắc chắn họ sẽ bỏ bình luận.


1

Đây là một biến thể cụ thể cho tất cả những người còn lại trong chúng ta đến cuối câu hỏi này:

ls -1 src/*.c | xargs -i sh -c "echo;gcc -fpreprocessed -dD -E {} 2>&1 | grep -wi -e one -e two -e three -n | sed 's:^:{}\::'" | cat -s

Một danh sách nếu tập tin nguồn C

ls -1 src/*.c

được dẫn đến xargs, thực thi bộ tiền xử lý trong shell con

gcc -fpreprocessed -dD -E {} 2>&1

mà sau đó được dẫn vào một lệnh grep mong muốn

grep -wi -e one -e two -e three -n

mà sau đó được dẫn vào sed để tiền tố mỗi dòng với tên tệp hiện tại

sed 's:^:{}\::'

Cuối cùng, tất cả các dòng trống lặp đi lặp lại được thu gọn thành các dòng đơn bằng cách sử dụng cat:

cat -s

Điều này hoạt động trên hệ thống RHEL6, nhưng tôi cho rằng nó đủ chung cho các hệ thống * nix khá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.