2010-04-22 7 views
9

Durante la ricerca di codice per le stringhe, mi imbatto costantemente nel problema che ottengo risultati privi di significato e privi di contesto. Ad esempio, se una chiamata di funzione è suddivisa su 3 righe e cerco il nome di un parametro, ottengo il parametro su una riga da solo e non il nome della funzione.Come faccio a grep per intere, possibilmente avvolte, linee di codice?

Ad esempio, in un file contenente

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

grep per MY_CONSTANT restituirebbe una linea che si presentava così:

    MY_CONSTANT, 

Allo stesso modo, in un blocco di commento:

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

Grepping per FIXMESOON fornisce la risposta molto frustrante:

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

Quando ci sono migliaia di accessi, i risultati a riga singola sono un po 'privi di significato. Quello che mi piacerebbe fare è che grep sia consapevole dei punti di inizio e di arresto delle linee del codice sorgente, qualcosa di così semplice da considerare ";" come il separatore di riga sarebbe un buon inizio.

Punti bonus se è possibile farlo restituire l'intero blocco di commenti se l'hit è all'interno di un commento.

So che non puoi farlo solo con grep. Sono anche consapevole dell'opzione di avere grep restituire un certo numero di righe di contesto. Qualche suggerimento su come realizzare sotto Linux? Cordiali saluti, le mie lingue preferite sono C e Perl.

Sono sicuro di poter scrivere qualcosa, ma so che qualcuno deve averlo già fatto.

Grazie!

+3

Boh, ma è una buona domanda! – mpen

+1

al posto di una buona soluzione, puoi sempre usare grep's '-C n' per' n' linee di contesto –

risposta

3

È possibile utilizzare pcregrep con l'opzione -M (corrispondenza multilinea; pcregrep è grep con espressioni regolari compatibili Perl). Qualcosa di simile:

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

Cool, in qualche modo mai saputo di pcregrep. Adoro il suggerimento sull'utilizzo: 'Uso: pcregrep [-ABCcDdeFfHhilLMNnoqrsuVvwx] [long options] [pattern] [files]'. Sempre bello sapere quali caratteri sono valide opzioni! – Cascabel

+0

... * sì *, opzione gonfia, che divertimento. –

+0

@wash - CHE opzione bloat ??? Hanno ancora 20 caratteri come non usati! – DVK

1

Puoi scrivere una riga di comando usando grep con le opzioni che ti danno il numero di riga e il nome del file, quindi xarg questi risultati in awk per analizzare queste colonne e poi usare un piccolo script da te per visualizzare le linee N che lo circondano linea? :)

1

Se questo non è uno sforzo accademico si potrebbe utilizzare cscope (per il codice C solo però). Se sei disposto a rinunciare al requisito di cercare nei commenti ctags dovrebbe essere sufficiente (e supporta anche Perl).

3

Ecco un esempio di utilizzo di 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) 

il concetto alla base: RS è separatore di record. impostandolo su ")", quindi ogni record nel file è separato da ")" invece di newline. Ciò semplifica la ricerca della "funzione1", poiché è possibile "grep" per esso. Se non usi awk, lo stesso concetto può essere applicato usando "splitting" su ")".

0

Avevo una situazione in cui avevo un file xml pieno dei nomi dei file zip in un formato di stile xml, cioè con le carote che racchiudevano i nomi dei file, ad esempio.zip < \ roba>

ho usato awk di cambiare tutte le carote in nuove righe grep poi utilizzato :)

Problemi correlati