Estoy tratando de usar grep
para unir líneas que contienen dos cadenas diferentes. He intentado lo siguiente, pero esto coincide con las líneas que contienen cadena1 o cadena2 que no es lo que quiero.
grep 'string1\|string2' filename
Entonces, ¿cómo hago coincidir grep
solo las líneas que contienen ambas cadenas ?
Respuestas:
Puedes usar
grep 'string1' filename | grep 'string2'
O,
grep 'string1.*string2\|string2.*string1' filename
fuente
grep -e "string1" -e "string2"
Creo que esto es lo que estabas buscando:
Creo que respuestas como esta:
solo coincida con el caso donde ambos están presentes, no uno u otro o ambos.
fuente
grep -e "string1" -e "string2" filename
haría lo mismo?How do I match lines that contains *both* strings?
Para buscar archivos que contengan todas las palabras en cualquier orden en cualquier lugar:
El primer grep inicia una búsqueda recursiva (
r
), ignorando mayúsculasi
y minúsculas ( ) y enumerando (imprimiendo) el nombre de los archivos que coinciden (l
) para un término ('action'
con comillas simples) que aparecen en cualquier parte del archivo.Los greps posteriores buscan los otros términos, conservan la insensibilidad de mayúsculas y minúsculas y enumeran los archivos coincidentes.
La lista final de archivos que obtendrá serán los que contienen estos términos, en cualquier orden en cualquier parte del archivo.
fuente
grep -ril 'foo' | xargs -d '\n' grep -il 'bar'
Si usted tiene una
grep
con una-P
opción para un número limitadoperl
de expresiones regulares, puede utilizarque tiene la ventaja de trabajar con cadenas superpuestas. Es algo más sencillo usar
perl
comogrep
, porque puede especificar la lógica y más directamente:fuente
Tu método era casi bueno, solo faltaba el -w
fuente
grep -V
.grep -w 'regexp1\|regexp2' filename
El
|
operador en una expresión regular significa o. Es decir, ya sea string1 o string2 coincidirán. Podrías hacerlo:que canalizará los resultados del primer comando al segundo grep. Eso debería darte solo líneas que coincidan con ambas.
fuente
Podrías probar algo como esto:
fuente
Y como la gente sugirió perl y python, y scripts de shell enrevesados, aquí hay un enfoque awk simple :
Después de mirar los comentarios a la respuesta aceptada: no, esto no hace líneas múltiples; pero eso tampoco es lo que pidió el autor de la pregunta.
fuente
No intentes usar grep para esto, usa awk en su lugar. Para unir 2 expresiones regulares R1 y R2 en grep, pensarías que sería:
mientras que en awk sería:
pero ¿qué
R2
pasa si se superpone o es un subconjunto deR1
? Ese comando grep simplemente no funcionaría mientras que el comando awk sí. Digamos que desea encontrar líneas que contenganthe
yheat
:Tendría que usar 2 greps y una tubería para eso:
y, por supuesto, si realmente hubiera requerido que estuvieran separados, siempre puede escribir en awk la misma expresión regular que usó en grep y hay soluciones alternativas awk que no implican repetir las expresiones regulares en cada secuencia posible.
Dejando eso de lado, ¿y si quisieras extender tu solución para que coincida con 3 expresiones regulares R1, R2 y R3? En resumen, esa sería una de estas malas elecciones:
mientras que en awk sería conciso, obvio, simple y eficiente:
Ahora, ¿qué pasa si realmente quisiera hacer coincidir las cadenas literales S1 y S2 en lugar de las expresiones regulares R1 y R2? Simplemente no puede hacer eso en una llamada a grep, debe escribir el código para escapar de todos los metacares RE antes de llamar a grep:
o de nuevo use 2 greps y una pipa:
que de nuevo son malas elecciones, mientras que con awk simplemente usa un operador de cadena en lugar del operador regexp:
Ahora, ¿qué pasaría si quisieras unir 2 expresiones regulares en un párrafo en lugar de una línea? No se puede hacer en grep, trivial en awk:
¿Qué tal en todo un archivo? Una vez más, no se puede hacer en grep y trivial en awk (esta vez estoy usando GNU awk para RS de múltiples caracteres por concisión, pero no es mucho más código en ningún awk o puedes elegir un control-char que sabes que no estar en la entrada para que el RS haga lo mismo):
Entonces, si desea encontrar múltiples expresiones regulares o cadenas en una línea, párrafo o archivo, no use grep, use awk.
fuente
awk '/R1/ && /R2/'
insensible a mayúsculas y minúsculas?awk -v IGNORECASE=1 '/R1/ && /R2/'
y con cualquier awkawk '{x=toupper($0)} x~/R1/ && x~/R2/'
GNU grep versión 3.1
fuente
Líneas encontradas que solo comienzan con 6 espacios y terminan con:
fuente
Digamos que necesitamos encontrar el recuento de varias palabras en un archivo de prueba. Hay dos formas de hacerlo
1) Use el comando grep con el patrón de coincidencia de expresiones regulares
2) Use el comando egrep
Con egrep no necesita preocuparse por la expresión y solo separar las palabras mediante un separador de tubería.
fuente
git grep
Aquí está la sintaxis
git grep
con múltiples patrones:También puede combinar patrones con expresiones booleanas como
--and
,--or
y--not
.Busca
man git-grep
ayuda.Otros parámetros a considerar:
Para cambiar el tipo de patrón, también se puede usar
-G
/--basic-regexp
(por defecto),-F
/--fixed-strings
,-E
/--extended-regexp
,-P
/--perl-regexp
,-f file
y otros.Relacionado:
Para la operación OR , ver:
fuente
Coloque las cadenas que desea grep en un archivo
Luego busque usando -f
fuente
obtendrá línea con string1 y string2 en cualquier orden
fuente
Esto funciona para la coincidencia exacta de palabras y las palabras que no distinguen entre mayúsculas y minúsculas, para eso se usa -i
fuente
para partido multilínea:
o
¡solo necesitamos eliminar el carácter de nueva línea y funciona!
fuente
Deberías haberlo hecho
grep
así:fuente
A menudo me encuentro con el mismo problema que el tuyo, y acabo de escribir una secuencia de comandos:
Uso:
Puede ponerlo en .bashrc si lo desea.
fuente
Cuando las dos cadenas están en secuencia, coloque un patrón en el
grep
comando:Ejemplo si las siguientes líneas están contenidas en un archivo llamado
Dockerfile
:Para obtener la línea que contiene las cadenas:
FROM python
yas build-python
luego use:Luego, la salida mostrará solo la línea que contiene ambas cadenas :
fuente
ripgrep
Aquí está el ejemplo usando
rg
:Es una de las herramientas de grepping más rápidas, ya que está construida sobre el motor regex de Rust que utiliza autómatas finitos, SIMD y optimizaciones literales agresivas para que la búsqueda sea muy rápida.
Úselo, especialmente cuando trabaja con datos de gran tamaño.
Consulte también la solicitud de funciones relacionadas en GH-875 .
fuente
string2
aparece antesstring1
. La solución más simple a este problema esrg string1 file.txt | rg string2
.