verdadero utilizar regulares puede patrones palabra los falso expresiones exacta ejemplos con comando caracteres busqueda buscar shell grep

shell - utilizar - ¿Qué comando grep incluirá el nombre de la función actual en su salida?



grep linux ejemplos (9)

Ejecuto diff con la opción -p para que la salida incluya el nombre de la función donde ocurrió cada cambio. ¿Hay una opción análoga para grep ? Si no, ¿qué otro comando podría usar en su lugar?

En lugar de -B para mostrar un número fijo de líneas de contexto que preceden inmediatamente a una coincidencia, me gustaría que la coincidencia esté precedida por una sola línea con la firma de función más reciente, sin embargo, muchas líneas atrás estaban en el archivo. Si la opción que estoy buscando fuera -p , la salida podría verse así, por ejemplo:

$ cat foo.c int func1(int x, int y) { return x + y; } int func2(int x, int y, int z) { int tmp = x + y; tmp *= z; return tmp; } $ grep -p -n -e ''return'' foo.c 1-int func1(int x, int y) 3: return x + y; -- 5-int func2(int x, int y, int z) 9: return tmp;


Al igual que con la mayoría de las operaciones de procesamiento de texto, es trivial con awk:

$ awk -v re=''return'' ''/^[[:alpha:]]/{f=FNR"-"$0} $0~re{printf "%s/n%d:%s/n--/n",f,FNR,$0; f="" }'' file 1-int func1(int x, int y) 3: return x + y; -- 5-int func2(int x, int y, int z) 9: return tmp; --

Lo anterior supone que la firma de una función es cualquier línea que comience con una letra (/ ^ [[: alpha:]] /). Si esa no es la forma en que se escribe su código, simplemente modifíquelo para adaptarlo.


Aquí hay una solución imperfecta. Tiene los siguientes defectos:

  1. Requiere una herramienta llamada ctags
  2. En consecuencia, funciona para archivos C, o cualquier idioma compatible con ctags, pero no más allá de eso
  3. Muestra todos los encabezados de función C, no importa qué. Este es el mayor problema con mi script, es posible que pueda encontrar una manera de superarlo.

Llamé a mi script `cgrep.sh '', que tiene la siguiente sintaxis:

cgrep.sh search-term files...

Cgrep.sh funciona confiando en ctags para producir una lista de patrones de búsqueda para encabezados de función. Luego podemos buscar tanto los encabezados de función como el término de búsqueda. Sin más preámbulos, aquí está cgrep.sh:

#!/bin/sh # Grep, which includes C function headers # cgrep term files* TERM=$1 # Save the search term shift ctags "$@" # produces the tags file sed -i.bak ''s:^.*/^:^:;s:/$::'' tags # Prepare the tags file for grep # Original contents is backed up to tags.bak grep -f tags -e $TERM "$@" # Grep both headers and search term rm tags tags.bak # Clean up


Aqui tienes:

git grep --no-index -n -p ''return''

Solo necesitas git. Los archivos que se buscan no tienen que formar parte de un repositorio git. Pero si lo son, entonces omita --no-index y obtén un impulso de velocidad instantáneo!


Asumiendo que estás buscando foobar:

grep foobar///|^//w.*/( *.h *.cpp | grep -B 1 foobar

greps para todas las funciones y todas las funciones de foobar, luego imprime los filtros solo para foobar y las líneas anteriores, que serán solo las funciones y las funciones que contienen. (probado en ubuntu bash)


En realidad, "grep -p" ha sido un elemento en AIX durante las últimas dos décadas, por lo que puedo recordar. Está ahí fuera, y es solo una cuestión de trasladar el comportamiento a un código nuevo.

Sin embargo, es burdo y puede necesitar ayuda para saber que las líneas en blanco dentro de una función no cuentan.


Escribí un script para grep archivos C y muestro los nombres y la firma de la función C junto con los resultados. Basado en ctags.

#!/bin/bash # # grep_c_code # # Grep C files and print the results along with the function name and signature. # Requires: ctags, gawk, sed, bash, and you probably want grep too. # # Written by David Stav, December 19 2012. # # Released to the public domain. # if [ $# -lt 2 ]; then echo "Usage: $0 <grep_cmd> <files/dirs...>" >&2 echo "" >&2 echo "Example:" >&2 echo " $0 ''grep --color=always -n -e /"PATTERN/"'' file1 file2 dir1 dir2 | less -R" >&2 exit 1 fi GREP_CMD="$1" shift GAWK_SCRIPT="` sed -n -e ''/^##### START of gawk script #####$/,/^##### END of gawk script #####$/p'' /"$0/" | / sed -n -e ''2,$ { $ D; p}'' `" ctags -f - -R --sort=no -n --fields=+afikKmsSzt --extra=+fq "$@" | / gawk "$GAWK_SCRIPT" "$GREP_CMD" | / bash exit 0 ##### START of gawk script ##### function parse_line(a) { a["tagname"] = $1; a["filename"] = $2; a["line_number"] = gensub(/^([0-9]+).*$/, "//1", 1, $3); if (a["line_number"] == $3) { a["line_number"] = "0"; } a["kind"] = gensub(/^.*/tkind:([^/t]+).*$/, "//1", 1, $0); if (a["kind"] == $0) { a["kind"] = "unknown kind"; } a["signature"] = gensub(/^.*/tsignature:(.*)$/, "//1", 1, $0); if (a["signature"] == $0) { a["signature"] = ""; } } function grep_section(a, next_line_number) { printf("/n"); printf("/n"); printf("/n"); printf("cat ''%s'' | ///n", a["filename"]); printf("sed -n -e ''%s,%sp'' | ///n", a["line_number"], next_line_number); printf("%s | ///n", grep_cmd); printf("sed -e ''1 i ///n"); printf("//n//n//n--///n"); printf("[%s:%s]///n", a["filename"], a["line_number"]); printf("<%s> %s%s///n", a["kind"], a["tagname"], a["signature"]); printf("''/n"); } BEGIN / { FS = "/t"; grep_cmd = ARGV[1]; ARGV[1] = "" } !/^!/ / { parse_line(next_line); if (a["line_number"]) { next_line_number = next_line["line_number"] - 1; grep_section(a, next_line_number); delete a; } for (key in next_line) { a[key] = next_line[key]; } } END / { if (a["line_number"]) { next_line_number = "$"; grep_section(a, next_line_number); } } ##### END of gawk script #####

Disfrutar. :)


Lamentablemente no. Esta característica no existe en grep ni existe en ack (que es un reemplazo de grep mejorado).

Aunque realmente desearía que esto existiera. Sería útil. discussed , pero no parece que su parche haya sido aceptado (o que alguna vez haya sido publicado en línea, de forma extraña). Puede intentar enviarle un correo electrónico y ver si todavía tiene el código y quiere obtener una opción para mostrar las funciones de C en grep .

Puedes escribir una expresión regular para que coincida con una función de C, pero apuesto a que sería un monstruo de una expresión regular.


No hay tal función en GNU grep, aunque se ha discussed en el pasado.

Sin embargo, si su código está bajo el control de git grep , git grep tiene una opción -p que lo hará.


Podría escribir un script que grep -v s en un archivo temporal y luego diff -p s que con el original. De esa forma, diff encontraría las líneas que grep eliminó (es decir, las líneas que desea) y obtendría la misma función exacta.