Granice słów grep

22

Zgodnie z dokumentacją GNU:

‘\<’ Match the empty string at the beginning of word.
‘\>’ Match the empty string at the end of word.

Mój / etc / fstab wygląda następująco:

/dev/sdb1       /media/fresh      ext2   defaults     0 0

Chcę, aby grep zwrócił wartość PRAWDA / FAŁSZ dla istnienia / media / fresh. Starałem się używać \<, a \>ale to nie działa. Czemu?

egrep '\</media/fresh\>' /etc/fstab

Obejście:

egrep '[[:blank:]]/media/fresh[[:blank:]]' /etc/fstab

Ale wygląda brzydiej.

Mój grep to 2.5.1

Felipe Alvarez
źródło
4
Przypuszczam, że /nie jest uważany za znak słowny, więc wyrażenie regularne nie pasuje - „\ b dopasowuje przed i po sekwencji alfanumerycznej” jest bardziej dokładne niż powiedzenie „przed i po słowie”
Felipe Alvarez

Odpowiedzi:

27

\<i \>dopasuj pusty ciąg odpowiednio na początku i na końcu słowa, a tylko znaki składowe słowa to:

[[:alnum:]_]

Od man grep:

Word-constituent characters are letters, digits, and the underscore.

Twój regex zawodzi, ponieważ /nie jest prawidłowym znakiem składającym się na słowo.

Zamiast tego, mając wokół siebie spacje, możesz użyć -wopcji grepdopasowania słowa:

grep -wo '/media/fresh' /etc/fstab

Przykład:

$ grep -wo '/media/fresh' <<< '/dev/sdb1       /media/fresh      ext2   defaults     0 0'
/media/fresh
heemayl
źródło
Liczę tak samo po opublikowaniu mojego pytania. Wszelkie sugestie dotyczące tego, co chcę osiągnąć?
Felipe Alvarez,
@FelipeAlvarez Sprawdź moje zmiany ..
heemayl
1

Ten problem ze \<(i również \b) dotyczy nie tylko /, ale wszystkich znaków innych niż słowa. (tj. znaki inne niż [[:alnum:]]i _.)

Problem polega na tym, że silnik wyrażeń regularnych zawsze omija znak niebędący słowem, na przykład /podczas wyszukiwania następnej kotwicy \<. Dlatego nie należy umieszczać znaków innych niż słowa, takich jak /zaraz po \<. Jeśli to zrobisz, z założenia nic nie będzie pasować.

Alternatywą dla -wopcji grep byłoby coś takiego:

egrep "(^|\W)/media/fresh($|\W)"
SE
źródło