texto regulares parametros palabras palabra expresiones exacta egrep contar comando buscar archivos grep

regulares - grep para 2 palabras existentes en la misma línea



grep buscar palabra exacta (8)

¿cómo grep para las líneas que contienen dos palabras de entrada en la línea? Estoy buscando líneas que contengan ambas palabras, ¿cómo hago eso? Probé con una pipa como esta:

grep -c "word1" |grep -r "word2" logs

simplemente sobresale después del primer comando de tubería. ¿por qué?


Prescripción

Una simple reescritura del comando en la pregunta es:

grep "word1" logs | grep "word2"

El primer grep encuentra líneas con ''word1'' del archivo ''logs'' y luego las introduce en el segundo grep que busca las líneas que contienen ''word2''.

Sin embargo, no es necesario usar dos comandos como ese. Puede usar grep extendido ( grep -E o egrep ):

grep -E ''word1.*word2|word2.*word1'' logs

Si sabes que ''word1'' precederá a ''word2'' en la línea, ni siquiera necesitas las alternativas y grep regular:

grep ''word1.*word2'' logs

Las variantes de ''un comando'' tienen la ventaja de que solo hay un proceso en ejecución, por lo que las líneas que contienen ''palabra1'' no tienen que pasarse por un conducto al segundo proceso. Cuánto importa esto depende de cuán grande es el archivo de datos y cuántas líneas coinciden con ''word1''. Si el archivo es pequeño, no es probable que el rendimiento sea un problema y ejecutar dos comandos está bien. Si el archivo es grande pero solo unas pocas líneas contienen ''word1'', no se pasarán muchos datos en la tubería y usar dos comandos está bien. Sin embargo, si el archivo es enorme y ''word1'' ocurre con frecuencia, entonces puede estar pasando datos significativos por el conducto donde un único comando evita esa sobrecarga. Contra eso, la expresión regular es más compleja; es posible que necesite compararla para descubrir qué es lo mejor, pero solo si el rendimiento realmente importa. Si ejecuta dos comandos, debe apuntar a seleccionar la palabra menos frecuente en el primer grep para minimizar la cantidad de datos procesados ​​por el segundo.

Diagnóstico

El script inicial es:

grep -c "word1" | grep -r "word2" logs

Esta es una secuencia de comando impar. El primer grep contará el número de apariciones de ''word1'' en su entrada estándar, e imprimirá ese número en su salida estándar. Hasta que indique EOF (por ejemplo, escribiendo Control-D ), se quedará allí, esperando que escriba algo. El segundo grep realiza una búsqueda recursiva de ''word2'' en los archivos debajo de los logs directorio (o, si es un archivo, en los logs archivos). O, en mi caso, fallará ya que no hay un archivo ni un directorio llamado logs donde estoy ejecutando la canalización. Tenga en cuenta que el segundo grep no lee su entrada estándar en absoluto, por lo que el tubo es superfluo.

Con Bash, el shell padre espera hasta que todos los procesos en la tubería hayan salido, por lo que se queda esperando que grep -c termine, lo que no sucederá hasta que indique EOF. Por lo tanto, su código parece bloquearse. Con Heirloom Shell , el segundo grep completa y sale, y el shell solicita nuevamente. Ahora tiene dos procesos en ejecución, el primer grep y el shell, y ambos están tratando de leer desde el teclado, y no está determinado cuál recibe una determinada línea de entrada (o cualquier indicación EOF dada).

Tenga en cuenta que incluso si escribió datos como entrada en el primer grep , solo obtendría líneas que contengan ''word2'' en la salida.

Nota:

En un momento, la respuesta utilizada:

grep -E ''word1.*word2|word2.*word1'' "$@" grep ''word1.*word2'' "$@"

Esto activó los comentarios a continuación.


El problema principal es que no ha suministrado el primer grep con ninguna entrada. Necesitarás reordenar tu comando algo así como

grep "word1" logs | grep "word2"

Si desea contar las ocurrencias, coloque una ''-c'' en el segundo grep.



Use grep:

grep -wE "string1|String2|...." file_name

O puede usar:

echo string | grep -wE "string1|String2|...."


Usted gato intenta con el comando debajo

cat log|grep -e word1 -e word2


podrías usar awk. Me gusta esto...

cat <yourFile> | awk ''/word1/ && /word2/''

El orden no es importante. Entonces, si tienes un archivo y ...

un archivo llamado, file1 contiene:

word1 is in this file as well as word2 word2 is in this file as well as word1 word4 is in this file as well as word1 word5 is in this file as well as word2

entonces,

/tmp$ cat file1| awk ''/word1/ && /word2/''

resultará en,

word1 is in this file as well as word2 word2 is in this file as well as word1

sí, awk es más lento.


¿Por qué pasas -c ? Eso solo mostrará el número de coincidencias. Del mismo modo, no hay ninguna razón para usar -r . Te sugiero que leas man grep .

Para grep para 2 palabras existentes en la misma línea, simplemente hazlo:

grep "word1" FILE | grep "word2"

grep "word1" FILE imprimirá todas las líneas que tengan word1 en ellas desde FILE, y luego grep "word2" imprimirá las líneas que tienen word2 en ellas. Por lo tanto, si combina estos utilizando una tubería, mostrará líneas que contienen tanto word1 como word2.

Si solo quieres contar cuántas líneas tenían las 2 palabras en la misma línea, hazlo:

grep "word1" FILE | grep -c "word2"

Además, para responder a su pregunta, ¿por qué se bloquea? En grep -c "word1" , no especificó ningún archivo. Por lo tanto, grep espera la entrada desde stdin , que es por lo que parece colgarse. Puede presionar Ctrl + D para enviar un EOF (fin de archivo) para que se cierre.


grep word1 file_name | grep word2

esa parece la forma más fácil para mí