Czy istnieje sposób, aby grep wyprowadzał „słowa” z plików pasujących do wyrażenia wyszukiwania?
Jeśli chcę znaleźć wszystkie wystąpienia np. „Th” w wielu plikach, mogę:
grep "th" *
ale wynik będzie podobny (pogrubiony przeze mnie);
niektóre-text-file: kot siedział na tej maty some-other-text-file: Szybki brązowy lis jeszcze inny plik tekstowy: mam nadzieję, że to dokładnie to wyjaśnia
To, co chcę, aby wyświetlało, używając tego samego wyszukiwania, to:
the
the
the
this
thoroughly
Czy jest to możliwe przy użyciu grep? Lub używając innej kombinacji narzędzi?
Odpowiedzi:
Spróbuj grep -o
Edycja: dopasowanie z komentarza Phila
Z dokumentów :
źródło
"\w*th\w*" *
oznacza, więc pomyślałem, że opublikuję.\w
to [_ [: alnum:]], więc w zasadzie pasuje do każdego „słowa” zawierającego „th” (ponieważ\w
nie zawiera spacji). * Po cytowanej sekcji jest globem, dla którego pliki (tzn.\w
zasadniczo nie jest przenośnygrep -E
; w celu zapewnienia odpowiedniej przenośności użyj[[:alnum:]]
zamiast tego nazwy klasy znaków POSIX (lub[_[:alnum:]]
jeśli naprawdę chcesz też podkreślenia; lub spróbuj,grep -P
jeśli Twoja platforma to ma).-h
jest to całkowicie konieczne, powiedziałbym ..?Bezpieczna odpowiedź na krzyżową dystrybucję (w tym Windows MinGW?)
Jeśli używasz starszych wersji grep (takich jak 2.4.2), które nie zawierają opcji -o. Użyj powyższego. W innym przypadku skorzystaj z prostszej wersji, aby zachować wersję poniżej.
Bezpieczna odpowiedź na dystrybucję w systemie Linux
Aby podsumować
-oh
wyniki, wyrażenie regularne pasuje do zawartości pliku (a nie jego nazwy pliku), podobnie jak oczekiwałbyś, że wyrażenie regularne będzie działać w vim / etc ... To, jakie słowo lub wyrażenie regularne będzie wtedy wyszukiwane, zależy od ty! Tak długo, jak pozostajesz w POSIX, a nie w perlowej składni (patrz poniżej)Więcej z instrukcji grep
Powód, dla którego oryginalna odpowiedź nie działa dla wszystkich
Użycie
\w
różni się w zależności od platformy, ponieważ jest to rozszerzona składnia „perl”. W związku z tym instalacje grep, które są ograniczone do pracy z klasami znaków POSIX,[[:alpha:]]
a nie ich odpowiednikiem w perlu\w
. Więcej informacji można znaleźć na stronie Wikipedii dotyczącej wyrażeń regularnychOstatecznie powyższa odpowiedź na POSIX będzie dużo bardziej niezawodna niezależnie od platformy (będącej oryginalną) dla grep
Jeśli chodzi o obsługę grep bez opcji -o, pierwszy grep wypisuje odpowiednie linie, tr dzieli spacje na nowe linie, a końcowe filtry grep tylko dla odpowiednich linii.
(PS: Wiem, że do tej pory większość platform zostałaby załatana dla \ w .... ale zawsze są takie, które pozostają w tyle)
Podziękowania za obejście „-o” z odpowiedzi @AdamRosenfield
źródło
-o
opcja nie jest dostępna w grep systemu Windows, który instaluje się z pakietem git (minGW?):"c:\Program Files (x86)\Git\bin\grep" --version grep (GNU grep) 2.4.2
To prostsze niż myślisz. Spróbuj tego:
Gdzie,
źródło
Możesz przetłumaczyć spacje na znaki nowej linii, a następnie grep, np .:
źródło
tr
, mógł zrobićgrep
najpierw, więctr
zostanie zastosowana tylko do pasujących linii:grep th filename | tr ' ' '\n' | grep th
Po prostu
awk
nie potrzebujesz kombinacji narzędzi.źródło
polecenie grep tylko dla dopasowania i perla
źródło
th
dlatego, że zażądałeś możliwie najkrótszego powtórzenia symbolu wieloznacznego.Nie byłem zadowolony z trudnej do zapamiętania składni awk, ale podobał mi się pomysł użycia jednego narzędzia do tego celu.
Wygląda na to, że ack (lub ack-grep, jeśli używasz Ubuntu) może to zrobić łatwo:
Jeśli pominiesz flagę -h, otrzymasz:
Jako bonus możesz użyć
--output
flagi, aby zrobić to w przypadku bardziej skomplikowanych wyszukiwań, korzystając z najłatwiejszej składni, jaką znalazłem:źródło
źródło
cat
?Aby wyszukać wszystkie słowa, zaczynając od „ikona-”, poniższe polecenie działa idealnie. Używam tutaj Ack , który jest podobny do grep, ale z lepszymi opcjami i ładnym formatowaniem.
źródło
Możesz także wypróbować pcregrep . Istnieje również
-w
opcja w grep , ale w niektórych przypadkach nie działa zgodnie z oczekiwaniami.Z Wikipedii :
źródło
Miałem podobny problem, szukając wyrażenia regularnego grep / pattern i „dopasowanego wzorca znalezionego” jako wyniku.
Na koniec użyłem egrep (ten sam regex na grep -e lub -G nie dał mi tego samego wyniku egrep) z opcją -o
więc myślę, że może to być coś podobnego (NIE jestem mistrzem wyrażeń regularnych):
źródło
{1}
kwantyfikatory powinny zostać porzucone. Lub jeśli chcesz być konsekwentnyt{1}h{1}e{1}
itp.Możesz przesłać dane wyjściowe grep do Perla w następujący sposób:
źródło
Fragment strony man grep:
-w: Wybierz tylko te wiersze zawierające dopasowania, które tworzą całe słowa. Test polega na tym, że pasujący podłańcuch musi znajdować się na początku wiersza lub poprzedzony znakiem składającym się z innych słów.
źródło
the
nie pasowało już np. „Te” lub „kąpać się”.ripgrep
Oto przykład z użyciem
ripgrep
:Dopasuje wszystkie pasujące słowa
th
.źródło