Megfigyelem a grep
következő viselkedését, amikor fut ötször:
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$
Nem tudtam megérteni, hogy a grep
utolsó két próbálkozása miért nem ad eredményt .
Válasz
grep
minták reguláris kifejezések (más néven regex, regexp, RE), basic reguláris kifejezések (BRE), kivéve, ha a -E
/ -F
/ -P
/ -K
/ -X
opciót használjuk (amelyek közül csak az első kettő szabványos).
*
egy regexp operátor, amely az előző atom nak legalább 0-nak megfelel. Például: d*
0 vagy több megegyezik d
s. BRE-kben, amikor a minta elején vagy ha a iv id = “50d2ddefce”>
vagy \(
regexp operátorok, ez csak egy szó szerinti *
(egyben szó szerint a [...]
zárójeles kifejezések belsejében).
Tehát a grep "*README.md*"
szó egyezik azokon a sorokon, amelyek szó szerinti *
, majd README
, majd bármelyik karakter (a .
regexp operátor), majd m
, amelyet tetszőleges számú d
követ. Mivel a tetszőleges számba 0 is beletartozik, ez funkcionálisan egyenértékű a grep "*README.m"
-vel (ami nem jelentene különbséget abban, hogy mely sorok illesztésre kerülnek, csak azon, ami illeszthető) a soron belül (ami például a GNU --color
opciójával megjelenik grep
)).
Például , megegyezik ezen a két vonalon:
*README mike ^^^^^^^^^ DONT***README-mddd ^^^^^^^^^^^^
(a ^
s megmutatja, mi illeszkedik a soron belülre a reguláris kifejezéssel, amelyet a --color
) kifejezéssel láthat,
Itt úgy tűnik, hogy összekeveri a reguláris kifejezéseket a héj helyettesítő karakterekkel. A 0 vagy több karakterrel egyező *
helyettesítő karakter operátor .*
írható reguláris kifejezésekbe. De a következő művelet:
grep ".*README\.md.*"
ismét ugyanaz lenne, mint:
grep "README\.md"
Mint grep
keres egyezést a soron belül , szemben azzal, hogy olyan vonalakat találjon, amelyek pontosan megfelelnek a mintának (ehhez szükség van -x
).
Ast-open grep
-vel, amely szintén ksh93
“s grep
beépített (alapértelmezés szerint nem mindig beépített, és engedélyeznie kell azt úgy, hogy a /opt/ast/bin
elemet a $PATH
), használhatja a -K
opciót a grep
számára a shell helyettesítő karakterek (kibővített ksh93) használatához. Tehát ezzel grep
megvalósítást megteheti:
grep -K "README.md"
vagy
grep -xK "*README.md*"
azokon a sorokon, amelyek README.md
tartalmaznak.
Ugyanezzel a megvalósítással a helyettesítő karakterek egyeztetése a kiterjesztetten belül is engedélyezhető (), kibővített (-X
) vagy perl-szerű (-P
) rendszeres (?K)
operátorral rendelkező kifejezések (és \(?K\)
az alapvető reguláris kifejezésekben, amelyek valójában megtörik a POSIX-konformitást, ezért nem hivatkoznék rá, mivel későbbi verzióban eltávolítható). Tehát megteheti:
grep -xE "(?K)*README.md*"
ott.
Bármely modern grep
megvalósítással, ezt is megteheti:
grep -F README.md
Rögzített karakterlánc kereséshez (ahol a fenti .
egyezik a literal .
minden karakter helyett).
Megjegyzések
m a sima grep
(vagy grep -G
) használatával is.
grep -K
, amely shell mintákat használ (ahol *
tetszőleges számú karakternek felel meg). *
nem különleges, ha egy BRE első karaktere, lásd: a POSIX specifikáció
+
a regex elején, és ugyanígygrep -P
grep -E
is több megvalósítással. Ezt*
szó szerint kezelték, ha az elején csak a BRE-knél van megadva. Más RE-kkel, YMMV.