Ho cercato di trovare un modo per filtrare una riga che contiene la parola "limone" e "riso". So come trovare "limone" o "riso", ma non i due. Non hanno bisogno di essere vicini all'altro, solo uno della stessa riga di testo.
Ho cercato di trovare un modo per filtrare una riga che contiene la parola "limone" e "riso". So come trovare "limone" o "riso", ma non i due. Non hanno bisogno di essere vicini all'altro, solo uno della stessa riga di testo.
Risposte:
"Entrambi sulla stessa linea" significa "riso" seguito da caratteri casuali seguiti da "limone" o viceversa ".
In regex che è rice.*lemon
o lemon.*rice
. Puoi combinarlo usando un |
:
grep -E 'rice.*lemon|lemon.*rice' some_file
Se si desidera utilizzare regex normale anziché quelli estesi ( -E
) è necessario una barra rovesciata prima di |
:
grep 'rice.*lemon\|lemon.*rice' some_file
Per altre parole che diventano rapidamente un po 'lunghe ed è generalmente più facile usare più chiamate di grep
, ad esempio:
grep rice some_file | grep lemon | grep chicken
grep rice
linee di ricerca contenenti rice
. È alimentato in grep lemon
cui troverà solo righe contenenti limone .. e così via. Considerando che il PO - così come le tue precedenti risposte - stanno permettendo uno qualsiasi di [riso | limone | pollo]
|
bisogna evadere grep
? Grazie!
egrep
usa regex esteso dove |
è inteso come logica OR. grep
per impostazione predefinita regex di base, dove si \|
trova OR
grep
manpage di, egrep
è obsoleto e deve essere sostituito da grep -E
. Mi sono preso la libertà di modificare la risposta di conseguenza.
È possibile reindirizzare l'output del primo comando grep a un altro comando grep e questo corrisponderebbe a entrambi i modelli. Quindi, puoi fare qualcosa del tipo:
grep <first_pattern> <file_name> | grep <second_pattern>
o,
cat <file_name> | grep <first_pattern> | grep <second_pattern>
Aggiungiamo alcuni contenuti al nostro file:
$ 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
Cosa contiene il file:
$ 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.
Ora, grep quello che vogliamo:
$ grep rice test_grep.txt | grep lemon
This line contains both lemon and rice.
This line also contains both rice and lemon.
Otteniamo solo le linee in cui entrambi i modelli corrispondono. Puoi estenderlo e reindirizzare l'output a un altro comando grep per ulteriori corrispondenze "AND".
grep con l' opzione -P
(Compatibilità Perl) e regex lookahead positivo(?=(regex))
:
grep -P '(?=.*?lemon)(?=.*?rice)' infile
oppure puoi usare qui sotto, invece:
grep -P '(?=.*?rice)(?=.*?lemon)' infile
.*?
mezzi di riscontro caratteri .
che gli eventi da zero o più volte *
, mentre sono opzionali seguiti da un modello ( rice
o lemon
). La ?
rende tutto facoltativa prima che (mezzi zero o una volta di tutto abbinato .*
)(?=pattern)
: Lookahead positivo: il costrutto lookahead positivo è una coppia di parentesi, con la parentesi aperta seguita da un punto interrogativo e un segno di uguale.
Quindi questo restituirà tutte le righe con contiene entrambi lemon
e rice
in ordine casuale. Anche questo eviterà di usare se |
raddoppiato grep
.
Collegamenti esterni:
Argomenti avanzati di Grep Lookahead positivo - GREP for Designers
Se ammettiamo che grep
è accettabile fornire una risposta che non è basata, come la risposta di cui sopra awk
, proporrei una perl
linea semplice come:
$ perl -ne 'print if /lemon/ and /rice/' my_text_file
La ricerca può ignorare il caso con alcune / tutte le parole come /lemon/i and /rice/i
. Sulla maggior parte delle macchine Unix / Linux, perl è installato e comunque awk.
Ecco uno script per automatizzare la soluzione di piping 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
inserirla, che si interrompe facilmente