Jak wyszukiwać tekst w całym systemie plików?


53

Zakładając, że należy użyć narzędzia grep, chciałbym wyszukać ciąg tekstowy „800x600” w całym systemie plików.

Próbowałem:

grep -r 800x600 /

ale to nie działa.

Moim zdaniem, moje polecenie powinno rekurencyjnie grepować przez wszystkie pliki / foldery w katalogu głównym dla tekstu „800x600” i wyświetlać wyniki wyszukiwania.

Co ja robię źle?


2
A przez „to nie działa” masz na myśli dokładnie to, co? Czy nie drukuje żadnych danych wyjściowych, zawiesza się ani nie drukuje wielu Permission deniedbłędów? Czy uruchomiłeś go jako root lub zwykły użytkownik?
alex

Tracę trochę, przede wszystkim byłem w katalogu domowym użytkownika, próbując uruchomić polecenie. Więc teraz mam cd / out do rootowania. Następnie wypróbowałem to samo polecenie jak powyżej i otrzymuję wiele błędów odmowy uprawnień. Ok, więc teraz próbuję sudo grep -r 800x600 /, a następnie dostaję / proc / sysrq-trigger: Błąd wejścia / wyjścia
Level1Coder

Hmm, nie wiem, dlaczego to nie zadziała. W ten sposób możesz zignorować błędy dostępu grep -r 800x600 / 2>/dev/null. Możesz także spróbować uruchomić go jako root.
Totor

Odpowiedzi:


64

Zwykle używam tego stylu poleceń do uruchamiania grepwielu plików:

find / -xdev -type f -print0 | xargs -0 grep -H "800x600"

W rzeczywistości robi to listę wszystkich plików w systemie, a następnie dla każdego pliku wykonuje się grepz podanymi argumentami i nazwą każdego pliku.

-xdevTeza mówi, że musi znaleźć ignorować inne systemy plików - jest to dobre dla uniknięcia specjalnych systemów plików, takich jak /proc. Jednak zignoruje również normalne systemy plików - więc jeśli na przykład folder / home znajduje się na innej partycji, nie zostanie przeszukany - trzeba by powiedzieć find / /home -xdev ....

-type foznacza wyszukiwanie tylko plików, więc katalogi, urządzenia i inne pliki specjalne są ignorowane (nadal będzie się powtarzało w katalogach i będzie działać grepna plikach w nim zawartych - po prostu nie uruchomi się grepna samym katalogu, co i tak by nie działało). I -Hopcja grepnakazująca mu zawsze drukować nazwę pliku na wyjściu.

findakceptuje wszelkiego rodzaju opcje filtrowania listy plików. Na przykład -name '*.txt'przetwarza tylko pliki z rozszerzeniem .txt. -size -2Moznacza pliki mniejsze niż 2 megabajty. -mtime -5oznacza pliki zmodyfikowane w ciągu ostatnich pięciu dni. Połącz je razem z -a dla i i -o dla lub i użyj '('nawiasów ')'do grupowania wyrażeń (w cudzysłowach, aby zapobiec ich interpretacji przez powłokę). Na przykład:

find / -xdev '(' -type f -a -name '*.txt' -a -size -2M -a -mtime -5 ')' -print0 | xargs -0 grep -H "800x600"

Spójrz na, man findaby zobaczyć pełną listę możliwych filtrów.


2
Pamiętaj, że -xdevwykluczy wszystkie inne systemy plików, nie tylko specjalne. (np. jeśli /homezamontowałeś jako oddzielną partycję, nie będzie ona przeszukiwana).
cjm

Próbowałem uruchomić każdy z nich, ale oba zwracają błąd -find: paths must precede expression: /
Level1Coder

1
Uwaga: Gdy wyrażenia regularne nie są wymagane, „fgrep” jest znacznie szybszy niż „grep”, co zrobi dużą różnicę w przypadku wyszukiwania dużego drzewa.
Nathan Kidd,

1
xargsRobiąc, możesz uniknąć przechodzenia z być może lepszą efektywnością find / -xdev -type f -exec grep -H '800x600' +.
Totor

3
Nie, +znak na końcu findpolecenia faktycznie robi to samo, co xargs: spawnuje jeden grepproces z kilkoma argumentami.
Totor

14

Zwykle nie chcesz przeszukiwać WSZYSTKO w systemie. Linux używa do wszystkiego węzłów plików, więc niektóre „pliki” nie są rzeczami, które chciałbyś przeszukać. Na przykład /dev/sdajest fizycznym urządzeniem blokującym dla pierwszego dysku twardego. Prawdopodobnie chcesz przeszukać podłączone systemy plików, a nie surowe urządzenie dyskowe. Jest też coś, /dev/randomco wyrzuca losowe dane za każdym razem, gdy je czytasz. Wyszukiwanie nie ma większego sensu. System /procplików jest również problematyczny w twoim przypadku.

Poleciłbym jedną z dwóch rzeczy.

  1. Nie szukaj w katalogu głównym, szukaj tylko miejsc, które mogą być przydatne. Szukaj /homelub /usrlub /etcSeparatly. Informacje, których szukasz, są prawdopodobnie określonego typu, więc i tak mogą znajdować się w określonym folderze. Ustawienia konfiguracji powinny być włączone /etc. Twoje pliki danych osobowych powinny znajdować się w /home. Ograniczenie wyszukiwania do tak dużego obszaru, jak ten, znacznie zmniejszy twoje problemy z rekurencyjnymi grepami.

  2. Wyklucz problematyczne obszary --exclude-diri zestaw rzeczy, których wiesz, że nie potrzebujesz:
    grep -r --exclude-dir /proc --exclude-dir /dev --exclude-dir /tmp --exclude-dir /lost+found

Wreszcie, często zdarza się napotkać kilka błędów „odmowy uprawnień” podczas wykonywania dużego rekurencyjnego grepa. W normalnym trybie użytkowania są pliki, których użytkownik może nie być w stanie odczytać. Dopóki są to tylko niektóre nieparzyste pliki, a nie surowe urządzenie dla twoich dysków twardych lub całego systemu plików proc, możesz po prostu zignorować błędy. W rzeczywistości możesz to zrobić w wierszu polecenia, wysyłając wszystkie błędy do nigdy nie wyląduj:

grep -r search_string /path 2> /dev/null

3
-Iwykluczać binarne
Rahul Patil

2

Dla uproszczenia sugerowałbym ack-grep . Link pokazuje wiele przypadków, kiedy ack-grepjest lepszym rozwiązaniem.

Aby użyć, po instalacji:

ack-grep pattern /

Dziękuję za polecenie, ale uruchomiłem to i tak naprawdę nie dało mi to oczekiwanych wyników wyszukiwania. Wydaje się, że będę musiał dostosować wiele ustawień, aby uzyskać to, czego chcę. Na razie odpowiedź Richarda działa od razu po wyjęciu z pudełka. Przyjrzymy się temu w przyszłości, ponieważ wydaje się to również przydatne.
Level1Coder

1

Innym sposobem patrzenia na to jest ten sposób:

grep -r /* | grep "800x600"

0

* następnie otrzymuję / proc / sysrq-trigger: błąd wejścia / wyjścia

Twoje polecenie działa, pojawia się ten błąd, ponieważ próbujesz skanować uruchomione procesy w poszukiwaniu łańcucha.

Polecam wykluczenie katalogów systemowych z

grep -exclude-dir = {proc, sys} "800x600" /


-3

po prostu w prawo-

grep -r "800x600" /

-Co jest nie tak w obecnym poleceniu, to cudzysłowy „”. Zawsze umieszczaj argument ciągu grepw cudzysłowie.


3
To nie jest problem tutaj. Nie potrzebujesz cudzysłowów, gdy podajesz ten konkretny typ argumentu grep. Spróbuj, a zobaczysz. Umieść ciąg „800x600” w pliku, a wtedy grep 800x600 filezobaczysz, że działa dobrze. OP ma oczywiście inny problem.
slm
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.