2010-04-22 16 views
9

Al buscar código para cadenas, constantemente me encuentro con el problema de que obtengo resultados sin sentido y sin contexto. Por ejemplo, si una llamada de función se divide en 3 líneas, y busco el nombre de un parámetro, obtengo el parámetro en una línea por sí mismo y no el nombre de la función.¿Cómo puedo grep para líneas de código enteras, posiblemente envueltas?

Por ejemplo, en un archivo que contiene

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

grepping para MY_CONSTANT devolvería una línea que se veía así:

    MY_CONSTANT, 

Del mismo modo, en un bloque de comentarios:

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

Grepping para FIXMESOON da la muy frustrante respuesta:

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

Cuando hay miles de visitas, los resultados de una sola línea son un poco insignificantes. Lo que me gustaría hacer es que grep esté al tanto de los puntos de inicio y fin de las líneas de código fuente, algo tan simple como tenerlo en cuenta ";" como el separador de línea sería un buen comienzo.

Puntos de bonificación si puede hacer que devuelva todo el bloque de comentarios si el hit está dentro de un comentario.

Sé que no puedes hacer esto con grep solo. También estoy al tanto de la opción de que grep devuelva una cierta cantidad de líneas de contexto. ¿Alguna sugerencia sobre cómo lograr en Linux? FYI mis idiomas preferidos son C y Perl.

Estoy seguro de que podría escribir algo, pero sé que alguien ya debe haber hecho esto.

Gracias!

+3

No sé, pero es una buena pregunta! – mpen

+1

en lugar de una buena solución, siempre puede usar grep '' -C n' para 'n' líneas de contexto –

Respuesta

3

Puede usar pcregrep con la opción -M (coincidencia de líneas múltiples; pcregrep es grep con expresiones regulares compatibles con Perl). Algo así como:

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

Cool, de alguna manera nunca supo de pcregrep. Me encanta la sugerencia de uso: 'Uso: pcregrep [-ABCcDdeFfHhilLMNnoqrsuVvwx] [opciones largas] [patrón] [archivos]'. ¡Siempre es bueno saber qué personajes son opciones válidas! – Cascabel

+0

... * sí *, opción de hinchazón, qué divertido. –

+0

@wash - ¿Qué opción hincharse ??? ¡Todavía tienen como 20 caracteres sin usar! – DVK

1

Puede escribir una línea de comando usando grep con las opciones que le dan el número de línea y el nombre del archivo, luego ajustar estos resultados en awk para analizar estas columnas y luego usar un pequeño script para mostrar las N líneas que lo rodean ¿línea? :)

1

Si esto no es una tarea académica es posible que utilices cscope (para el código C sólo embargo). Si está dispuesto a abandonar el requisito de buscar en los comentarios, el ctags debería ser suficiente (y también es compatible con Perl).

3

Aquí hay un ejemplo con 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) 

el concepto detrás de: RS is record separator. estableciéndolo en ")", entonces cada registro en su archivo está separado por ")" en lugar de nueva línea. Esto hace que sea más fácil encontrar su "función1" ya que puede "grep" para ello. Si no usa awk, se puede aplicar el mismo concepto usando "división" en ")".

0

Tuve una situación en la que tenía un archivo xml lleno de los nombres de los archivos zip en un formato de estilo xml, es decir, con zanahorias entre corchetes con los nombres de los archivos, por ejemplo.zip < \ stuff>

Solía ​​awk para cambiar todas las zanahorias en nuevas líneas grep luego se usa :)

Cuestiones relacionadas