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.*lemon
o 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 rice
líneas de búsqueda que contienen rice
. Se alimenta en el grep lemon
que 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!
egrep
usa expresiones regulares extendidas donde |
se entiende como lógica OR. grep
el valor predeterminado es regex básico, donde \|
es OR
grep
la página del manual, egrep
está 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 ( rice
o 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 lemon
y rice
en orden aleatorio. Además, esto evitará el uso de |
sy doblado grep
s.
Enlaces externos:
Temas Grep avanzados Lookahead positivo - GREP para diseñadores
Si admitimos que proporcionar una respuesta que no está grep
basada es aceptable, como la respuesta anterior basada en awk
, propondría una perl
lí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 "$@"
eval
ing, que se rompe fácilmente