Możliwa duplikat:
Wyszukaj wzór tekstowy w systemie Linux
W bashie zastanawiałem się, czy istnieją jakieś polecenia, które poinformują cię, czy określony ciąg znaków istnieje w plikach znajdujących się w bieżącym katalogu, w którym się znajdujesz.
Załóżmy, że szukasz funkcji „toUpperCase ()” w zestawie plików C w bieżącym katalogu. Istnieje wiele plików, więc nie chcesz ręcznie otwierać każdego z nich za pomocą vima i sprawdzać łańcucha „toUpperCase”, ponieważ zajęłoby to dużo czasu. Jeśli nie jest to linia poleceń bash, czy istnieje inna metoda, aby zrobić to skutecznie?
Standardowym narzędziem wyszukiwania tekstu jest grep .
Aby wyszukać ciąg
toUpperCase(
we wszystkich.c
plikach w bieżącym katalogu:Jeśli chcesz również zajrzeć do podkatalogów:
Jeśli szukasz C wywołań funkcji, a następnie ctags może być lepsze dopasowanie. Uruchom go raz na wszystkich plikach źródłowych, aby utworzyć indeks identyfikatorów, a następnie użyj edytora do nawigacji między połączeniami. Wszystkie edytory podobne do vi mogą używać
TAGS
pliku ctags . Jeśli używasz Emacsa, uruchom podobny programetags
.źródło
ctags
jest przydatny do znajdowania definicji funkcji , a nie wywołań funkcji .Używasz vima. Masz wbudowane narzędzie do wykonania tego.
Jak można się spodziewać, jest już siedem odpowiedzi, z których należy skorzystać
grep
. Ale wydaje mi się, że do tej pory byłem jedyną osobą, która zauważyła twoje pytanie, którego używaszvim
. Jako takie, chociaż można używaćgrep
od wewnątrzvim
, można również użyćvim
„s wbudowane narzędzie. Jest to wywoływane za pomocą:vimgrep
polecenia.Aby wyszukać „wszystkie pliki źródłowe C w bieżącym katalogu w poszukiwaniu wywołań funkcji
toUpperCase()
”, należy wpisaćvim
polecenieWynikowa lista dopasowań jest automatycznie ładowana do listy szybkich poprawek, dostępnej za pomocą jednego z nich (zobacz subtelną różnicę w pomocy online)
Aby znaleźć definicję funkcji , a nie wywołania,
ctags
jest to narzędzie, jak wspomniano wGilles
odpowiedzi , w połączeniu z poleceniami:tjump
lub:tselect
.Dlaczego warto korzystać
:vimgrep
?Pomoc on-line (
:help grep
) wylicza kilka powodów, których tutaj nie będę papugować. Oprócz tego porównaj działanie:vimgrep
zdietbuddha
odpowiedzią .dietbuddha
Wiersz poleceń wyświetla osobnygrep
proces dla każdego pliku źródłowego C. Nie stosuje się nawetxargs
do zmniejszenia tego narzutu. I nadal musisz jakoś przeanalizować dane wyjściowe, aby wywołać edytor tekstowy na odpowiednich plikach źródłowych po zakończeniu.:vimgrep
wcale nie rozwidla wielu dodatkowych procesów, a korzystanie z rezultatów to sama prostota. Samo wybranie jednego z wpisów na wynikowej liście poprawek automatycznie ustawia kursor w odpowiednim wierszu odpowiedniego pliku źródłowego.W rzeczywistości robi dokładnie to, co napisałeś, robiłbyś ręcznie, z wyjątkiem automatycznego. To zautomatyzowany sposób wykonywania tych czynności edytora tekstu. Ładuje plik tak, jakby był ładowany ręcznie, wyszukuje w nim wyrażenie regularne (używając tej samej składni wyrażeń regularnych, z której korzystasz już gdzie indziej
vim
), rejestruje miejsca, w których występują dopasowania, a następnie zwalnia plik.źródło
Tak, narzędzie to się nazywa
grep
.Podstawowe użycie to:
Lub dokładniej:
W bardzo prostym przypadku rekurencyjnie chcesz przeszukiwać wszystkie pliki, dlatego podajesz
-r
opcję. Jeśli nie przejmujesz się pisaniem wielkimi lub małymi literami, ustaw-i
opcję rozróżniania wielkości liter .Jeśli chcesz tylko pasujące części, skorzystaj z
-o
opcji.Grep może używać wyrażeń regularnych i ma ogromny podręcznik .
źródło
grep
to standardowa odpowiedź - użycie flagi -r do wyszukiwania rekurencyjnego lub w połączeniu zfind
(dyskusja i przykłady w innych pytaniach na tej stronie, takich jak ta )Moim ulubionym wyborem jest ostatnio
ack
. Prawdopodobnie nie jest zainstalowany na twoim komputerze, ale możesz zainstalować za pomocą apt-get na Ubuntu lub po prostu pobrać. Linki, instrukcje i powody, dla których jest lepszy niż grep, są dostępne na stronie http://betterthangrep.com/źródło
find
igrep
find myproject -name '*.c' -exec grep 'toUpperCase(' {} \; -print
dlaczego nie tylko
grep
?grep -r string .
przejdzie przez wszystkie pliki w bieżącym katalogu. Jeśli masz pliki obiektowe lub inne pliki binarne, możesz odzyskać zgodność z wynikami binarnymi, inaczej. dżonka. Jeśli w podkatalogu masz również pliki FOSO lub pliki urządzeń, możesz mieć nieznane / niezamierzone konsekwencje.grep string *.c
przeszukuje tylko bieżące.c
pliki katalogów .grep string **/*.c
przeszukuje wszystkie podkatalogi. Jeśli jednak masz bardzo dużą liczbę.c
plików, istnieje ryzyko przekroczenia maksymalnej liczby rozszerzeń globu powłoki. Ekspansja musi także nastąpić jako pierwsza, co oznacza pełne przejście drzewa, zanimgrep
zacznie się.źródło
Grep załatwi sprawę, ale odrobina dodatkowego skryptu pomoże znaleźć nazwę pliku i dokładną linię, do której się odwołuje. Jeśli to jest to, co chcesz, uważam, że następujące działa dobrze. Mam go zapisany jako skrypt powłoki i przekazuję mu wartość, którą chcę jako pierwszą opcję wiersza poleceń.
źródło
Interesujące jest dla mnie to, że nikt nie odpowiedział na twoje pytanie: „jak mogę sprawdzić, czy w plikach znajdujących się w bieżącym katalogu istnieje określony ciąg znaków”. O ile mi wiadomo, nie ma opcji grep, która zwraca tylko to, czy znaleziono dopasowanie w grupie plików. Najbliższą opcją jest -l, aby wyświetlić listę nazw plików. Najbliższa odpowiedź spośród tych jak dotąd dotyczy czasu, z pewnymi drobnymi poprawkami:
Możesz uczynić ten skrypt powłoki bardziej ogólnym, akceptując drugi argument rozszerzenia pliku bez większych problemów.
doug
źródło