Posible duplicado: busque
un patrón de texto en Linux
En bash, me preguntaba si había algún comando que le permitiera saber si una cadena particular que está buscando existe dentro de los archivos ubicados en el directorio actual en el que se encuentra.
Supongamos que está buscando la función 'toUpperCase ()' dentro de un conjunto de archivos C en su directorio actual. Hay muchos archivos, por lo que no querrá abrir cada uno manualmente usando vim y verificar la cadena 'toUpperCase' porque eso tomaría mucho tiempo. Si no es una línea de comando bash, ¿hay otro método para hacerlo de manera eficiente?
La herramienta de búsqueda de texto estándar es grep .
Para buscar la cadena
toUpperCase(
en todos los.c
archivos en el directorio actual:Si desea buscar también en subdirectorios:
Si está buscando llamadas a funciones C, entonces ctags puede ser mejor. Lo ejecuta una vez en todos sus archivos de origen para crear un índice de identificadores, luego usa su editor para navegar entre las llamadas. Todos los editores similares a vi pueden usar el
TAGS
archivo de ctags . Si usa Emacs, ejecute el programa similaretags
.fuente
ctags
es útil para encontrar definiciones de funciones , no llamadas de funciones .Estás usando vim. Tienes una herramienta para hacer esto incorporada.
Como era de esperar, hay siete respuestas que ya dicen usar
grep
. Pero parece ser la única persona hasta ahora que se ha dado cuenta de su pregunta que está utilizandovim
. Como tal, aunque se puede utilizargrep
desde dentrovim
, se puede también utilizarvim
's herramienta integrada. Esto se invoca a través del:vimgrep
comando.Para buscar "todos los archivos fuente de C en el directorio actual para llamadas a la función
toUpperCase()
" uno escribe elvim
comandoLa lista de coincidencias resultante se carga automáticamente en la lista de soluciones rápidas, a la que se puede acceder con cualquiera de los dos (consulte la ayuda en línea para ver la sutil diferencia)
Para encontrar la definición de la función , en lugar de las llamadas,
ctags
es la herramienta, como se menciona enGilles
la respuesta de , junto con los comandos:tjump
o:tselect
.¿Por qué usar
:vimgrep
?La ayuda en línea (
:help grep
) enumera varias de las razones, que no mencionaré aquí. Además de eso, compare la acción de:vimgrep
condietbuddha
la respuesta de .dietbuddha
La línea de comando de la horquilla bifurca ungrep
proceso individual para cada archivo fuente C individual. Ni siquiera se empleaxargs
para reducir esa sobrecarga. Y aún tiene que analizar de alguna manera el resultado para invocar su editor de texto en los archivos fuente relevantes una vez que haya terminado.:vimgrep
no bifurca múltiples procesos adicionales en absoluto, y usar el resultado es la simplicidad misma. Simplemente seleccionando una de las entradas en la lista de soluciones rápidas resultante, se posiciona automáticamente el cursor en la línea relevante del archivo fuente relevante.De hecho, hace exactamente lo que escribiste que harías a mano, excepto automáticamente. Es la forma automatizada de hacer esas mismas acciones del editor de texto. Carga el archivo como si se cargara a mano, busca una expresión regular (usando la misma sintaxis de expresión regular que ya está usando en otra parte
vim
), registra los lugares donde ocurren las coincidencias y luego descarga el archivo.fuente
Sí, se llama la herramienta
grep
.El uso básico es:
O, más específicamente:
En un caso muy simple, desea buscar de forma recursiva en todos los archivos, por lo que proporciona la
-r
opción. Si no le importan las mayúsculas o minúsculas, no distinga entre mayúsculas y minúsculas con la-i
opción.Si solo desea las partes coincidentes, use la
-o
opción.Grep puede usar expresiones regulares , y tiene un gran manual .
fuente
grep
es la respuesta estándar: usar el indicador -r para buscar de forma recursiva o en conjunto confind
(discusión y ejemplos en otras preguntas en este sitio, como este )Mi elección preferida últimamente es
ack
. Probablemente no esté instalado en su computadora, pero puede instalarlo usando apt-get en Ubuntu o simplemente descargarlo. Los enlaces, instrucciones y razones por las que es mejor que grep están disponibles en http://betterthangrep.com/fuente
find
ygrep
find myproject -name '*.c' -exec grep 'toUpperCase(' {} \; -print
¿Por qué no solo
grep
?grep -r string .
se repetirá a través de todos los archivos en el directorio actual. Si tiene archivos de objetos u otros archivos binarios, puede obtener una coincidencia con resultados binarios aka. basura. Si también tiene archivos de dispositivo o de Fifos en su subdirectorio, puede tener consecuencias desconocidas / no deseadas.grep string *.c
solo busca los.c
archivos de directorios actuales .grep string **/*.c
busca en todos los subdirectorios. Sin embargo, si tiene una gran cantidad de.c
archivos, corre el riesgo de exceder la cantidad máxima de expansiones para el shell glob. La expansión también tiene que suceder primero, lo que significa un recorrido completo del árbol antes de quegrep
comience.fuente
Grep hará el truco, pero un poco de secuencia de comandos adicional ayudará a encontrar el nombre del archivo y la línea exacta referenciada. Si eso es lo que quieres, creo que lo siguiente funciona bien. Lo tengo guardado como un script de shell y le paso el valor que quiero como primera opción de línea de comando.
fuente
Me parece interesante que nadie haya respondido a su pregunta específica: "¿cómo puedo encontrar si existe una cadena en particular dentro de los archivos ubicados en el directorio actual". Hasta donde sé, no hay una opción grep que solo devuelva si se ha encontrado una coincidencia en un grupo de archivos. La opción más cercana es -l para enumerar los nombres de archivo. La respuesta más cercana entre las que hasta ahora es de tim, con algunos pequeños ajustes:
Puede hacer que este script de shell sea más genérico aceptando un segundo argumento para la extensión del archivo sin demasiados problemas.
Doug
fuente