varios varias usar sólo start siguientes regulares que patrones palabras palabra mostrará líneas los las expresiones exacta egrep cuál con comienzan comandos buscar regex perl shell unix grep

regex - varias - ¿Cómo hacer coincidir una vez por archivo en grep?



usar grep (6)

¿Hay alguna opción de grep que me permita controlar el número total de coincidencias, pero se detiene en la primera coincidencia en cada archivo?

Ejemplo:

Si hago esto grep -ri --include ''*.coffee'' ''re'' . Entiendo esto:

./app.coffee:express = require ''express'' ./app.coffee:passport = require ''passport'' ./app.coffee:BrowserIDStrategy = require(''passport-browserid'').Strategy ./app.coffee:app = express() ./config.coffee: session_secret: ''nyan cat''

Y si hago grep -ri -m2 --include ''*.coffee'' ''re'' . , Entiendo esto:

./app.coffee:config = require ''./config'' ./app.coffee:passport = require ''passport''

Pero, lo que realmente quiero es esta salida:

./app.coffee:express = require ''express'' ./config.coffee: session_secret: ''nyan cat''

Hacer -m1 no funciona ya que obtengo esto para grep -ri -m1 --include ''*.coffee'' ''re'' .

./app.coffee:express = require ''express''

Intenté no usar grep, por ejemplo, este find . -name ''*.coffee'' -exec awk ''/re/ {print;exit}'' {} /; find . -name ''*.coffee'' -exec awk ''/re/ {print;exit}'' {} /; producido:

config = require ''./config'' session_secret: ''nyan cat''

ACTUALIZACIÓN: Como se indica a continuación, la opción GNU grep -m trata los recuentos por archivo, mientras que -m para BSD grep lo trata como un recuento global de coincidencias


¡Puedes hacerlo fácilmente en Perl, y sin problemas de plataforma cruzada!

use strict; use warnings; use autodie; my $match = shift; # Compile the match so it will run faster my $match_re = qr{$match}; FILES: for my $file (@ARGV) { open my $fh, "<", $file; FILE: while(my $line = <$fh>) { chomp $line; if( $line =~ $match_re ) { print "$file: $line/n"; last FILE; } } }

La única diferencia es que debe usar expresiones regulares de estilo Perl en lugar de estilo GNU. No son muy diferentes .

Puede hacer la parte recursiva en Perl usando File :: Find , o usar los archivos find feed it.

find /some/path -name ''*.coffee'' -print0 | xargs -0 perl /path/to/your/program


Creo que puedes hacer algo como

grep -ri -m1 --include ''*.coffee'' ''re'' . | head -n 2

por ejemplo, elegir el primer partido de cada archivo, y elegir como máximo dos partidos en total.

Tenga en cuenta que esto requiere que grep trate el -m como un límite de coincidencia por archivo; GNU grep hace esto, pero BSD grep aparentemente lo trata como un límite de coincidencia global.


Entonces, usando grep , solo necesitas la opción -l, --files-with-matches .

Todas esas respuestas sobre find , awk o scripts están fuera de la pregunta.


Haría esto en awk en su lugar.

find . -name /*.coffee -exec awk ''/re/ {print FILENAME ":" $0;exit}'' {} /;

Si no necesita recurse, puede hacerlo con awk:

awk ''/re/ {print FILENAME ":" $0;nextfile}'' *.coffee

O bien, si está utilizando bash lo suficientemente actual, puede usar globstar:

shopt -s globstar awk ''/re/ {print FILENAME ":" $0;nextfile}'' **/*.coffee


usando find y xargs. encuentre cada archivo .coffee y ejecute -m1 grep en cada uno de ellos

find . -print0 -name ''*.coffee''|xargs -0 grep -m1 -ri ''re''

prueba sin -m1

linux# find . -name ''*.txt''|xargs grep -ri ''oyss'' ./test1.txt:oyss ./test1.txt:oyss1 ./test1.txt:oyss2 ./test2.txt:oyss1 ./test2.txt:oyss2 ./test2.txt:oyss3

agregar -m1

linux# find . -name ''*.txt''|xargs grep -m1 -ri ''oyss'' ./test1.txt:oyss ./test2.txt:oyss1


find . -name /*.coffee -exec grep -m1 -i ''re'' {} /;

La opción find -exec ejecuta el comando una vez para cada archivo coincidente (a menos que utilice + lugar de /; lo que lo hace actuar como xargs).