He estado tratando de encontrar una manera de filtrar una línea que contenga las palabras "limón" y "arroz". Sé cómo encontrar "limón" o "arroz", pero no los dos. No necesitan estar uno al lado del otro, solo uno en la misma línea de texto.
He estado tratando de encontrar una manera de filtrar una línea que contenga las palabras "limón" y "arroz". Sé cómo encontrar "limón" o "arroz", pero no los dos. No necesitan estar uno al lado del otro, solo uno en la misma línea de texto.
Respuestas:
"Ambos en la misma línea" significa "'arroz' seguido de caracteres aleatorios seguidos de 'limón' o al revés".
En regex que es rice.*lemono lemon.*rice. Puedes combinar eso usando |:
grep -E 'rice.*lemon|lemon.*rice' some_file
Si desea utilizar expresiones regulares normales en lugar de expresiones extendidas ( -E), necesita una barra diagonal inversa antes de |:
grep 'rice.*lemon\|lemon.*rice' some_file
Para más palabras que rápidamente se vuelven un poco largas y generalmente es más fácil usar múltiples llamadas de grep, por ejemplo:
grep rice some_file | grep lemon | grep chicken
grep ricelíneas de búsqueda que contienen rice. Se alimenta en el grep lemonque solo encontrará líneas que contengan limón ... y así sucesivamente. Mientras que el OP, así como sus respuestas anteriores, permiten cualquiera de [arroz | limón | pollo]
|hay que escapar grep? ¡Gracias!
egrepusa expresiones regulares extendidas donde |se entiende como lógica OR. grepel valor predeterminado es regex básico, donde \|es OR
grepla página del manual, egrepestá en desuso y debe reemplazarse por grep -E. Me tomé la libertad de editar la respuesta en consecuencia.
Puede canalizar la salida del primer comando grep a otro comando grep y eso coincidiría con ambos patrones. Entonces, puedes hacer algo como:
grep <first_pattern> <file_name> | grep <second_pattern>
o,
cat <file_name> | grep <first_pattern> | grep <second_pattern>
Agreguemos algunos contenidos a nuestro archivo:
$ echo "This line contains lemon." > test_grep.txt
$ echo "This line contains rice." >> test_grep.txt
$ echo "This line contains both lemon and rice." >> test_grep.txt
$ echo "This line doesn't contain any of them." >> test_grep.txt
$ echo "This line also contains both rice and lemon." >> test_grep.txt
Qué contiene el archivo:
$ cat test_grep.txt
This line contains lemon.
This line contains rice.
This line contains both lemon and rice.
This line doesn't contain any of them.
This line also contains both rice and lemon.
Ahora, busquemos lo que queremos:
$ grep rice test_grep.txt | grep lemon
This line contains both lemon and rice.
This line also contains both rice and lemon.
Solo obtenemos las líneas donde ambos patrones coinciden. Puede extender esto y canalizar la salida a otro comando grep para otras coincidencias "Y".
grep con la opción -P (Perl-Compatibility) y regex positivo anticipado(?=(regex)) :
grep -P '(?=.*?lemon)(?=.*?rice)' infile
o puede usar a continuación, en su lugar:
grep -P '(?=.*?rice)(?=.*?lemon)' infile
.*?medios coinciden con los caracteres .que ocurren cero o más veces *mientras son opcionales seguidos de un patrón ( riceo lemon). El ?hace que todo sea opcional antes de que (medios cero o una vez de todo lo emparejados .*)(?=pattern): Búsqueda hacia adelante positiva: La construcción de búsqueda hacia adelante positiva es un par de paréntesis, con el paréntesis de apertura seguido de un signo de interrogación y un signo igual.
Entonces esto devolverá todas las líneas con contiene ambos lemony riceen orden aleatorio. Además, esto evitará el uso de |sy doblado greps.
Enlaces externos:
Temas Grep avanzados Lookahead positivo - GREP para diseñadores
Si admitimos que proporcionar una respuesta que no está grepbasada es aceptable, como la respuesta anterior basada en awk, propondría una perllínea simple como:
$ perl -ne 'print if /lemon/ and /rice/' my_text_file
La búsqueda puede ignorar mayúsculas y minúsculas con algunas / todas las palabras como /lemon/i and /rice/i. En la mayoría de las máquinas Unix / Linux, perl está instalado y awk de todos modos.
Aquí hay un script para automatizar la solución de tuberías grep:
#!/bin/bash
# Use filename if provided as environment variable, or "foo" as default
filename=${filename-foo}
grepand () {
# disable word splitting and globbing
IFS=
set -f
if [[ -n $1 ]]
then
grep -i "$1" ${filename} | filename="" grepand "${@:2}"
else
# If there are no arguments, assume last command in pipe and print everything
cat
fi
}
grepand "$@"
evaling, que se rompe fácilmente