Osservo il seguente comportamento di grep
quando lo eseguo cinque volte:
me@asus:~/go/src/company/topology-front$ lsof |grep "READ" vim 4788 me 4u REG 8,2 12288 32247694 /home/me/go/src/company/topology-front/.README.md.swp me@asus:~/go/src/company/topology-front$ lsof |grep "README.md*" vim 4788 me 4u REG 8,2 12288 32247694 /home/me/go/src/company/topology-front/.README.md.swp me@asus:~/go/src/company/topology-front$ lsof |grep "README.md" vim 4788 me 4u REG 8,2 12288 32247694 /home/me/go/src/company/topology-front/.README.md.swp me@asus:~/go/src/company/topology-front$ lsof |grep "*README.md*" me@asus:~/go/src/company/topology-front$ lsof |grep "*README.md" me@asus:~/go/src/company/topology-front$
Non sono riuscito a “capire perché gli ultimi due tentativi di grep
non restituiscono alcun risultato .
Answer
grep
i pattern sono espressioni regolari (note anche come regex, regexp, RE), espressioni regolari di base (BRE) a meno che una di -E
/ -F
/ -P
/ -K
/ -X
(solo le prime due delle quali standard) viene utilizzata.
*
è un operatore regexp che corrisponde a 0 o più dei precedenti atom . Ad esempio, d*
corrisponde a 0 o più d
s. In BRE, quando allinizio del pattern o quando si segue iv id = “50d2ddefce”>
o \(
operatori regexp, corrisponde solo a un *
letterale (è anche preso letteralmente allinterno di [...]
espressioni tra parentesi).
Quindi grep "*README.md*"
corrisponde a righe che contengono un seguito da README
seguito da un singolo carattere (loperatore .
regexp) seguito da m
seguito da qualsiasi numero di d
. Poiché qualsiasi numero include 0, è funzionalmente equivalente a grep "*README.m"
(che non farebbe differenza a quali linee vengono abbinate, solo su ciò che può essere abbinato allinterno della riga (che verrebbe visualizzata con lopzione --color
di GNU grep
per esempio)).
Ad esempio , corrisponderebbe su queste 2 righe:
*README mike ^^^^^^^^^ DONT***README-mddd ^^^^^^^^^^^^
(le ^
mostrano cosa corrisponde allinterno della riga dallespressione regolare, che potresti vedere con --color
)
Qui, sembra che tu “stia confondendo le espressioni regolari con i caratteri jolly della shell. Il *
operatore jolly che corrisponde a 0 o più caratteri può essere scritto .*
nelle espressioni regolari. Ma fare:
grep ".*README\.md.*"
sarebbe di nuovo uguale a:
grep "README\.md"
As grep
cerca una corrispondenza allinterno della riga invece di trovare righe che corrispondono esattamente allo schema (per cui è necessario -x
).
Con ast-open grep
, che è anche ksh93
“s grep
integrato (non sempre integrato per impostazione predefinita ed è necessario abilitarlo inserendo /opt/ast/bin
davanti a $PATH
), puoi utilizzare lopzione -K
per grep
per utilizzare i caratteri jolly della shell (quelli ksh93 estesi). Quindi con questo grep
, puoi eseguire le seguenti operazioni:
grep -K "README.md"
o
grep -xK "*README.md*"
per trovare corrispondenze su righe che contengono README.md
.
Con la stessa implementazione, la corrispondenza con caratteri jolly può essere abilitata anche allinterno di Extended (), aumentata (-X
) o perl-like (-P
) regolare espressioni con loperatore (?K)
(e \(?K\)
nelle espressioni regolari di base che effettivamente infrange la conformità POSIX, quindi non ci farei affidamento su di esso in quanto potrebbe essere rimosso in una versione futura). Quindi puoi fare:
grep -xE "(?K)*README.md*"
lì.
Con qualsiasi implementazione moderna di grep
, puoi anche fare:
grep -F README.md
Per una ricerca a stringa fissa (dove .
sopra corrisponde a un .
invece di qualsiasi carattere).
*
o+
allinizio della regex, così comegrep -P
grep -E
con diverse implementazioni. Questo*
trattato letteralmente quando allinizio è specificato solo per i BRE. Con altri RE, YMMV.grep
(ogrep -G
) semplice.grep -K
che utilizza modelli di shell (dove*
corrisponde a qualsiasi numero di caratteri).*
non è speciale quando il primo carattere di un BRE, vedi la specifica POSIX