Puede hacer búsquedas solo a través de archivos que coinciden con un patrón específico 'glob' (por ejemplo: buscar foo en todos los archivos llamados "bar * .c"). El comando
ack foo "bar*.c"
solo funciona en el directorio actual.
Nota: Sé que es posible con find -exec:
find . -name "bar*.c" -type f -exec ack foo {} +
Pero me gustaría un comando ack pequeño y simple, porque find no omite los directorios de control de versiones.
find . -name "bar*.c" -exec ack foo {} \;
? No tiene nada de especialgrep
, puede usar cualquier comando con find's-exec
.Respuestas:
Buscando directorios
Según la sinopsis que se muestra en la página de manual, diría que sí, puede procesar un directorio, pero al mirar los interruptores no puede buscar solo un archivo basado en un patrón. Para eso tendrás que alistarte
find
. El comandoack
incluye la opción--files-from=FILE
para que se pueda alimentar una lista de archivosfind
.sinopsis
uso
Existe la
--ignore-file=
opción que puede darle lo que desea, pero parece un poco difícil de usar.Buscar tipos específicos de archivos
La única otra forma en que puedo concebir hacer esto
ack
es usar su--type
interruptor:Para ver qué tipos están disponibles:
formato. Por ejemplo, tanto --type = perl como --perl funcionan. - [no] cpp .cpp .cc .cxx .m .hpp .hh .h .hxx - [no] objcpp .mm .h - [no] perl .pl .pm .pod .t .psgi; primera línea coincide con /^#!.*\bperl/ - [no] perltest .t
Ejemplos
Encuentre todos los archivos Perl, en función del nombre de archivo (* .pm, * .pl, * .t y * .pod) y la línea shebang.
Encuentra todos los archivos C ++:
Buscando a foo en el bar * .c
Entonces, ¿cómo puedes lograr lo que quieres? Bueno, probablemente tengas que usar
find
para hacer esto:También puede usar
ack
la capacidad de buscar archivos que coincidan con un patrón determinado en sus nombres de archivo (usando-g <pattern>
), y luego pasar esta lista a una segunda invocación deack
usar-x
o--files-from=-
...Utilizando
-x
:Utilizando
-files-from=-
:En cualquier caso, estamos haciendo coincidir los nombres de archivo que desea con esta expresión regular:
Esto coincide con los archivos cuyo nombre es
bar.*c
y final después del.c
uso final de la línea de anclaje,$
. También buscamos asegurarnos de que los nombres tengan un carácter de límite usando\b
. Esto fallará para los archivos que contienen caracteres de límite como$bar.c
o%bar.c
por ejemplo.fuente
cpp
archivosack --type=cpp <string>
. Consulteack
la página de manual para obtener más información sobre todo esto. Pero lo que básicamente te digo es que no puedes buscar deack
la manera que quieras.ack
que no puede hacer lo que se le pidió.find adir -iname "bar*.c" | ack --files-from=- foo
. O, si solo quiere un archivo:echo "barBaz.c" | ack --files-from=- foo
ack -g '\bbar.*.c$' | ack -x foo
Es fácil si se conoce el tipo de archivo, y ack conoce muchos tipos de archivos. Entonces, si, por ejemplo, desea buscar solo en archivos C, entonces puede hacerlo:
Pero si no es una de las extensiones conocidas, debe definir su propio tipo. Esto debería funcionar:
Tenga en cuenta que necesita tanto --type-set como --barc.
(Gracias a Andy, quien también ayudó con esto en la lista de correo).
fuente
man ack
realmente no ayuda y no tienecc
cuando busco eso."¿Qué hay de nuevo en ack 2?" http://beyondgrep.com/ack-2.0/
Solo que no puedo hacer que funcione:
Por lo tanto, parece que -g necesita una expresión regular, mientras que yo quiero una opción de estilo 'glob' ...
fuente
-g
toma una expresión regular, no un globo. Podrías escribir tu expresión regular como.*bar.*\.c$
.Esto parece ser el más rápido y seguro:
-x Lea la lista de archivos para buscar desde STDIN.
Sin embargo, si es probable que el archivo esté en su
locate
base de datos, esto sería aún más rápido:Localizar también puede aceptar expresiones regulares de la vieja escuela, un poco dolorosas, pero si está buscando
c
archivos, puede ser necesario. p.ejEso solo se traduce en: "buscar todos los nombres de archivo que terminan en c, cpp, h, hpp o cc".
fuente
Ack no admite la selección de archivos de estilo global. Como realmente extraño esto, creé un pequeño script de shell ackg :
Ahora puedes usar el comando:
Pero tenga en cuenta: desafortunadamente, esto también buscará en los directorios de control de versiones (por ejemplo: .git).
fuente
Esto se puede hacer con la
-G
opción de ag, el buscador de plata (un clon mejorado de ack-grep).Notas:
ag
usa la sintaxis de expresión regular PCRE , por lo que la expresión regular debe ser enbar.*\.c
lugar debar*.c
.-G
opción debe preceder al término de búsqueda, ya que cualquier cosa después de eso se interpreta como un nombre de archivo.fuente
¿Desea solo un cierto patrón, o solo quiere archivos fuente C?
Si desea todos los archivos C, use
Si desea todos los archivos C y NO los archivos de encabezado C, use
fuente
La respuesta de @chim es la mejor, pero está escrita como un comentario, así que la vuelvo a publicar como una respuesta formal ...
Me gusta el hecho de que puedes regex el camino ...
fuente
Usando zsh puedes hacer:
fuente
ls
.