2010-04-22 30 views
9

Khi tìm kiếm mã cho chuỗi, tôi liên tục gặp phải sự cố mà tôi nhận được kết quả vô nghĩa, ít bối cảnh. Ví dụ, nếu một cuộc gọi chức năng được chia trên 3 dòng, và tôi tìm kiếm tên của một tham số, tôi nhận được tham số trên một dòng của chính nó và không phải là tên của hàm.Làm cách nào để grep cho toàn bộ, có thể được bao bọc, các dòng mã?

Ví dụ, trong một tập tin chứa

... 
    someFunctionCall ("test", 
        MY_CONSTANT, 
        (some *really) - long/expression); 

grepping cho MY_CONSTANT sẽ trả về một dòng trông như thế này:

    MY_CONSTANT, 

Tương tự như vậy, trong một khối bình luận:

///////////////////////////////////////// 
// FIXMESOON, do..while is the wrong choice here, because 
// it makes the wrong thing happen 
///////////////////////////////////////// 

Tham lam cho FIXMESOON mang lại câu trả lời rất bực bội:

// FIXMESOON, do..while is the wrong choice here, because 

Khi có hàng nghìn lần truy cập, kết quả một dòng là vô nghĩa. Những gì tôi muốn làm là có grep được nhận thức của điểm bắt đầu và điểm dừng của dòng mã nguồn, một cái gì đó đơn giản như có nó xem xét ";" vì bộ tách dòng sẽ là một khởi đầu tốt.

Điểm thưởng nếu bạn có thể đặt nó trở lại toàn bộ khối nhận xét nếu lần truy cập nằm trong nhận xét.

Tôi biết bạn không thể làm điều này với grep một mình. Tôi cũng nhận thức được tùy chọn để có grep trả về một số dòng ngữ cảnh nhất định. Bất kỳ đề xuất về cách thực hiện theo Linux? FYI ngôn ngữ ưa thích của tôi là C và Perl.

Tôi chắc chắn rằng tôi có thể viết một cái gì đó, nhưng tôi biết rằng ai đó phải đã làm điều này.

Cảm ơn!

+3

Dunno, nhưng đó là một câu hỏi hay! – mpen

+1

thay cho một giải pháp tốt, bạn luôn có thể sử dụng '-C n' của grep cho các dòng' n' của ngữ cảnh –

Trả lời

3

Bạn có thể sử dụng pcregrep với tùy chọn -M (kết hợp nhiều dòng; pcregrep là grep với cụm từ thông dụng tương thích Perl). Một cái gì đó như:

pcregrep -M ";*\R*.*thingtosearchfor*\R*.*;.*" 
+0

Mát mẻ, bằng cách nào đó không bao giờ biết về pcregrep. Yêu gợi ý sử dụng: 'Cách dùng: pcregrep [-ABCcDdeFfHhilLMNnoqrsuVvwx] [tùy chọn dài] [mẫu] [tệp]'. Luôn luôn tốt để biết những gì nhân vật là lựa chọn hợp lệ! – Cascabel

+0

... * yeah *, tùy chọn sưng lên, những gì thú vị. –

+0

@wash - GÌ tùy chọn sưng lên ??? Họ vẫn còn 20 ký tự chưa được sử dụng! – DVK

1

Bạn có thể viết dòng lệnh bằng grep với các tùy chọn cung cấp cho bạn số dòng và tên tệp, sau đó xarg các kết quả này thành các phân tích và sau đó sử dụng một đoạn mã nhỏ từ bạn để hiển thị N dòng xung quanh hàng? :)

1

Nếu đây không phải là nỗ lực học thuật bạn chỉ có thể sử dụng cscope (chỉ với mã C). Nếu bạn sẵn sàng bỏ yêu cầu để tìm kiếm trong các bình luận ctags là đủ (và nó cũng hỗ trợ Perl).

3

Đây là ví dụ sử dụng awk.

$ cat file 
blah1 
blah2 
    function1 ("test", 
        MY_CONSTANT, 
        (some *really) - long/expression); 

function2(one , two) 
blah3 
blah4 

$ awk -vRS=")" '/function1/{gsub(".*function1","function1");print $0RT}' file 
function1 ("test", 
        MY_CONSTANT, 
        (some *really) 

khái niệm đằng sau: RS là bộ tách bản ghi. bằng cách đặt nó thành ")", thì mọi bản ghi trong tệp của bạn được phân cách bằng ")" thay vì dòng mới. Điều này làm cho nó dễ dàng để tìm thấy "function1" của bạn kể từ khi bạn có thể "grep" cho nó. Nếu bạn không sử dụng awk, khái niệm tương tự có thể được áp dụng bằng cách sử dụng "tách" trên ")".

0

Tôi đã có một tình huống trong đó tôi đã có một tệp xml đầy đủ tên của tệp zip theo định dạng kiểu xml, nghĩa là, với cà rốt với tên của tệp, ví dụ.nén < \ thứ>

tôi đã sử dụng awk để thay đổi tất cả cà rốt vào dòng mới sau đó sử dụng grep :)

Các vấn đề liên quan