2012-09-16 16 views
5

Estoy buscando ayuda con grep o grep como herramientas. Esto incluye pero no se limita a grep, egrep, awk, sed o cualquier otra herramienta que se use para buscar coincidencias. Pero lo llamaré grep por el resto de la pregunta.grep/grep rápido solo para el número de línea?

Estoy buscando la manera más rápida de grep un archivo para una coincidencia, y también estoy buscando la manera más rápida para grep un archivo para un partido y para devolver el número de línea no en el resto de la coincidencia línea. No me importa si la sintaxis es compleja siempre y cuando sea rápida, voy a usarla en un programa. La complejidad no es el problema.

También necesito este método para trabajar si necesito regex para un patrón así que también puedo buscar un rango. Entonces, si necesito buscar todos los números menores a 10 si el comando lo admite de manera predeterminada o si es necesario que contenga alguna expresión regular, solo estoy buscando el método más rápido que pueda encontrar.

gracias.

Editar

Los archivos que trabajo va a ser muy grande, mi archivo de prueba es 1.9GB

Respuesta

5

Creo que es KingsIndian en el blanco con la opción -m a grep, pero si la velocidad es su principal objetivo, cut puede ser más rápido que awk para este uso particular. Proveedores:

grep -n -m 1 regex file | cut -d: -f1 

el argumento -d: le dice a cortar a utilizar los dos puntos como separador de campos, mientras que el argumento -f1 le dice que sólo se emite el primer campo.

+0

Esto funciono igual que los otros pero si funciono un poquito mas rapido en promedio unos cientos de milisegundos. Supongo que si tuviera que omitir algunos, haría grep -n -m 10 archivo de expresiones regulares | cola -5 | cut -d: -f1 – WojonsTech

+0

Cuando se utiliza el corte, ¿cómo se especifica una pestaña como separador? – Bulrush

+0

cortar usa la pestaña como separador de manera predeterminada, así que simplemente elimine el -d: – nullrevolution

3

Para detener después de que el primer partido:

grep -n -m 1 str file | awk -F: '{print $1}' 

Usted puede cambiar el valor del argumento de m a un valor diferente para detener después de tantas coincidencias. La parte awk es capurar solo el número de línea.

Para detener después de 5 partidos:

grep -n -m 5 str file | awk -F: '{print $1}' 

Editar:
Usted puede utilizar tail para eso. Por ejemplo, para saltar primeros 5 partidos e imprimir el próximo 7: grep -n -m 12 str file| tail -7 | awk -F: '{print $1}'

+0

la -m es decir muy bien conoce usted si hay una manera de omitir los primeros resultados y luego imprimir los 5 siguientes y salir. es algo que voy a necesitar en este proyecto, pero también estoy trabajando en generar todo por el momento. – WojonsTech

+1

@WojonsTech editado para eso. –

+0

eso es genial, nunca lo pensé de esa manera. ¿Sabes si hay algo más rápido que awk en lo que le estamos pidiendo que haga, o es más rápido simplemente devolver el grep que no es forzar a awk a recorrer el conjunto de resultados? – WojonsTech

1

no estoy seguro de si esto es rápido, pero esto parece funcionar:

nl -b a "<filename>" | grep "<phrase>" | awk '{ print $1 }' 
+0

esto funciona, pero sé que en lugar de usar nl puede ue grep -n obtener la salida con los números de línea. – WojonsTech

1

Usted puede hacer uso de coincidencia de patrones y GNU awk simplemente imprima los números de línea:

awk '/regex/ { print NR }' file.txt 

valores son Suponiendo espacio separado, se pueden encontrar los números de línea si las líneas contienen números menores que 10:

awk '{ for (i=1; i<=NF; i++) if ($i <= 10) print NR }' file.txt 

Sin embargo, esto imprimirá el número de línea de cada aparición de un número menor que 10. Creo que puede encontrar esto indeseable. Por lo tanto, para eliminar varios números de línea duplicado para cada partido, puede utilizar una matriz:

awk '{ for (i=1; i<=NF; i++) if ($i <= 10) array[NR]++ } END { for (i in array) print i }' file.txt 

Si se necesita una salida ordenada hay que desviar a sort -n. Si prefiere una solución más elegante (es decirsin tuberías):

awk '{ for (i=1; i<=NF; i++) if ($i <= 10) array[NR]++ } END { for (j in array) sorted[k++]=j+0; n = asort(sorted); for (j=1; j<=n; j++) print sorted[j] }' file.txt 

EDIT:

En cualquiera de los últimos tres awk comandos anteriores, basta con cambiar if ($i <= 10) a if ($i >= 11 && $i <= 20) para mostrar los resultados del 11 al 20 inclusive.

+0

no es exactamente lo que estaba buscando pero parece ser la manera programática de resolverlo usando awk – WojonsTech

+0

@WojonsTech: Actualice su pregunta con _exactly_ lo que quiere hacer. Por lo que entiendo, quiere buscar algunas expresiones regulares e imprimir el número de línea y/o la línea correspondiente. Quizás no tenía claro lo último. En esta instancia, pruebe: 'awk '/ regex/{print NR, $ 0}' file.txt'. HTH. – Steve

+0

También estaba buscando la menor cantidad de hevery del sistema para usarlo. He visto cosas donde la gente usa grep y cut, y funciona bastante rápido. No estoy seguro de cómo se acumula la awk, pero vi que funcionó, pero ¿está buscando la mejor manera de limitar los resultados? – WojonsTech

1

acabo de hacer algunas pruebas con una llamada SED no bifurcante y no fue suerte, pero para referencia aquí los números con un archivo de texto 1 Gigabyte, donde mi $ PATRÓN es parte de la última línea:

(alerón: grep es más de 5 veces más rápido en esta operación, awk es más lento)

 
[email protected]:~$ ls -lh /dev/shm/test 
-rw-r--r-- 1 user user 979M Jul 8 09:50 /dev/shm/test 
 
[email protected]:~$ sed --version | head -n1 
GNU sed-Version 4.2.1 
[email protected]:~$ time sed -n "/$PATTERN/{=;q}" /dev/shm/test 
206558 

real 0m6.835s 
user 0m6.160s 
sys 0m0.648s 
 
[email protected]:~$ grep -V | head -n1 
grep (GNU grep) 2.14 
[email protected]:~$ time grep -n -m 1 "$PATTERN" /dev/shm/test | cut -d: -f1 
206558 

real 0m1.337s 
user 0m0.592s 
sys 0m0.736s 
 
[email protected]:~$ awk --version | head -n1 
GNU Awk 4.0.1 
[email protected]:~$ time awk "/$PATTERN/ { print NR }" /dev/shm/test 
206558 

real 0m7.176s 
user 0m6.356s 
sys 0m0.776s 

Cuestiones relacionadas