Wiem, że to stary wątek, ale natknąłem się na niego i pomyślałem, że udostępnię moją metodę, która okazała się bardzo szybkim sposobem find
znajdowania tylko plików niebinarnych:
find . -type f -exec grep -Iq . {} \; -print
-I
Opcja grep mówi to natychmiast ignorować pliki binarne i .
opcji wraz z -q
uczyni go natychmiast dopasować pliki tekstowe tak to idzie bardzo szybko. Jeśli martwisz się o spacje, możesz zmienić na -print
a, -print0
aby rurować w xargs -0
coś lub coś takiego (dzięki za wskazówkę, @ lucas.werkmeister!)
Również pierwsza kropka jest konieczna tylko dla niektórych wersji BSD, find
takich jak na OS X, ale nic nie szkodzi, po prostu posiadanie jej przez cały czas, jeśli chcesz umieścić to w aliasie lub coś w tym rodzaju.
EDYCJA : Jak poprawnie zauważył @ruslan, -and
można pominąć, ponieważ jest to zasugerowane.
find . -type f -exec grep -Il "" {} \;
.find -type f -exec grep -Iq . {} \; -and -print
który ma tę zaletę, że przechowuje plikifind
; możesz zastąpić-print
innym,-exec
który jest uruchamiany tylko dla plików tekstowych. (Jeśli pozwoliszgrep
wydrukować nazwy plików, nie będziesz w stanie rozróżnić nazw plików zawierających nowe linie.)find . -type f -exec grep -Il . {} +
jest znacznie szybszy. Wadą jest to, że nie można go przedłużyć o inny,-exec
jak sugerował @ lucas.werkmeisterNa podstawie tego pytania SO :
grep -rIl "needle text" my_folder
źródło
-I
to ratuje życie.Dlaczego jest to nieporęczne? Jeśli potrzebujesz go często i nie chcesz wpisywać go za każdym razem, po prostu zdefiniuj dla niego funkcję bash:
włóż go do swojego
.bashrc
i po prostu uruchom:kiedykolwiek chcesz.
EDYTUJ, aby odzwierciedlić edycję OP:
jeśli chcesz wyciąć informacje mime, możesz po prostu dodać kolejny etap do potoku, który odfiltrowuje informacje mime. To powinno załatwić sprawę, biorąc tylko to, co jest przed
:
:cut -d':' -f1
:źródło
file
podręcznika: „Użytkownicy polegają na tym, że wiedzą, że wszystkie czytelne pliki w katalogu mają wydrukowane słowo 'tekst'."/proc/meminfo
,/proc/cpuinfo
Itd. Są to pliki tekstowe, alefile /proc/meminfo
mówi/proc/meminfo: empty
. Zastanawiam się, czy „pusty” powinien być testowany oprócz „tekstu”, ale nie jestem pewien, czy inne typy mogą również zgłaszać „puste”.Niestety nie jest to oszczędność miejsca. Umieszczenie tego w skrypcie bash sprawia, że jest to trochę łatwiejsze.
To jest bezpieczne dla przestrzeni:
źródło
text.bin
? 2. Co się stanie, jeśli nazwa pliku zawiera:
?Inny sposób na zrobienie tego:
Jeśli chcesz również puste pliki:
źródło
Co powiesz na to:
Jeśli chcesz, aby nazwy plików nie zawierały typów plików, po prostu dodaj ostatni
sed
filtr.Możesz odfiltrować niepotrzebne typy plików, dodając więcej
-e 'type'
opcji do ostatniegogrep
polecenia.EDYTOWAĆ:
Jeśli twoja
xargs
wersja obsługuje tę-d
opcję, powyższe polecenia stają się prostsze:źródło
Oto, jak to zrobiłem ...
1. zrób mały skrypt do sprawdzenia, czy plik jest zwykłym tekstem istext:
2. użyj find jak poprzednio
źródło
== *"text"* ]]
?Mam dwa problemy z odpowiedzią na histumność:
Zawiera tylko pliki tekstowe. W rzeczywistości nie przeszukuje ich zgodnie z żądaniem. Aby faktycznie wyszukiwać, użyj
Tworzy proces grep dla każdego pliku, który jest bardzo wolny. Wtedy jest lepsze rozwiązanie
lub po prostu
Zajmuje to tylko 0,2 sekundy w porównaniu do 4 sekund w przypadku powyższego rozwiązania (2,5 GB danych / 7700 plików), czyli 20 razy szybciej .
Ponadto nikt nie wymienił ag, Silver Searcher lub ACK-GREP jako alternatyw. Jeśli jeden z nich jest dostępny, są znacznie lepszymi alternatywami:
Na koniec uważaj na fałszywe alarmy (pliki binarne traktowane jako pliki tekstowe). Miałem już fałszywy alarm przy użyciu grep / ag / ACK, więc lepiej najpierw wymień pasujące pliki przed ich edycją.
źródło
Chociaż jest to stare pytanie, myślę, że poniższe informacje dodadzą jakości odpowiedzi tutaj.
Ignorując pliki z ustawionym bitem wykonywalnym , po prostu używam tego polecenia:
Aby zapobiec rekurencyjnemu wchodzeniu do innych katalogów:
Nie potrzeba potoków do mieszania wielu poleceń, wystarczy potężne polecenie zwykłego wyszukiwania .
To powiedziawszy, mam nadzieję, że jest to przydatne dla każdego.
źródło
Robię to w ten sposób: 1) ponieważ jest zbyt wiele plików (~ 30k) do przeszukiwania, codziennie generuję listę plików tekstowych do użytku przez crontab za pomocą poniższego polecenia:
2) utwórz funkcję w .bashrc:
Następnie mogę użyć poniższego polecenia, aby przeprowadzić wyszukiwanie:
HTH :)
źródło
Wolę xargi
jeśli twoje nazwy plików są dziwne, poszukaj opcji -0:
źródło
grep eth0 $ (znajdź / etc / -type f -exec plik {} \; | egrep -i "tekst | ascii" | cut -d ':' -f1)
źródło
Oto uproszczona wersja z rozszerzonym wyjaśnieniem dla początkujących, takich jak ja, którzy próbują nauczyć się umieszczać więcej niż jedno polecenie w jednej linii.
Gdybyś miał opisać problem w krokach, wyglądałoby to tak:
Aby to osiągnąć, możemy użyć trzech poleceń UNIX:
find
,file
, igrep
.find
sprawdzi każdy plik w katalogu.file
poda nam typ pliku. W naszym przypadku szukamy zwrotu „tekstu ASCII”grep
będzie szukać słowa kluczowego „ASCII” w danych wyjściowych zfile
Jak więc możemy połączyć je w jedną linię? Jest na to wiele sposobów, ale uważam, że robienie tego w kolejności naszego pseudokodu ma największy sens (szczególnie dla początkującego, takiego jak ja).
find ./ -exec file {} ";" | grep 'ASCII'
Wygląda na skomplikowane, ale nieźle, kiedy to rozbijemy:
find ./
= przejrzyj każdy plik w tym katalogu. Wfind
komenda odchodzący nazwa pliku z dowolnego pliku, który pasuje do „wyrażenia” lub cokolwiek przyjdzie po ścieżce, która w naszym przypadku jest bieżący katalog lub./
Najważniejszą rzeczą do zrozumienia jest to, że wszystko po tym pierwszym bicie zostanie ocenione jako Prawda lub Fałsz. Jeśli prawda, nazwa pliku zostanie wydrukowana. Jeśli nie, to polecenie przechodzi dalej.
-exec
= ta flaga jest opcją w poleceniu find, która pozwala nam użyć wyniku innego polecenia jako wyrażenia wyszukiwania. To jak wywołanie funkcji w funkcji.file {}
= polecenie wywoływane wewnątrzfind
.file
Polecenie zwraca ciąg znaków, który powie Ci filetype pliku. Regularnie, to będzie wyglądać następująco:file mytextfile.txt
. W naszym przypadku chcemy, aby używał dowolnego pliku przeglądanego przezfind
polecenie, więc wstawiamy nawiasy klamrowe,{}
aby działały jako pusta zmienna lub parametr. Innymi słowy, po prostu prosimy system o wypisanie ciągu dla każdego pliku w katalogu.";"
= jest to wymagane przezfind
i jest znakiem interpunkcyjnym na końcu naszego-exec
polecenia. Jeśli potrzebujesz więcej wyjaśnień, skorzystaj z instrukcji „znajdź”man find
.| grep 'ASCII'
=|
jest rurą. Potok pobiera dane wyjściowe z tego, co jest po lewej stronie i używa ich jako danych wejściowych dla tego, co jest po prawej stronie. Pobiera dane wyjściowefind
polecenia (ciąg, który jest typem pliku pojedynczego pliku) i testuje je, aby sprawdzić, czy zawiera ciąg'ASCII'
. Jeśli tak, zwraca prawdę.TERAZ, wyrażenie po prawej
find ./
stronie zwróci wartość true, gdygrep
polecenie zwróci wartość true. Voila.źródło
Jeśli chcesz znaleźć dowolny typ pliku według ich magicznych bajtów, używając niesamowitego
file
narzędzia połączonego z mocąfind
, może się to przydać:Wynik:
Legenda:
$
to interaktywna zachęta powłoki, w której wpisujemy nasze poleceniaMożesz zmodyfikować część po,
&&
aby wywołać inny skrypt lub wykonać inne czynności w tekście, np. Jeśli ten plik zawiera podany ciąg, wpisz cały plik lub poszukaj w nim dodatkowego ciągu.Wyjaśnienie:
find
elementy, które są plikamixargs
kanał każdego elementu jako wiersz w jednymbash
poleceniu / skrypcie liniowymfile
sprawdza typ pliku po magicznym bajcie,grep
sprawdza, czy istnieje ASCII, jeśli tak, to po&&
wykonaniu następnego polecenia.find
wypisuje wynikinull
oddzielone, dobrze jest zmienić nazwy plików ze spacjami i metaznakami.xargs
, używając-0
opcji, czyta jenull
oddzielnie,-I @@
bierze każdy rekord i używa jako parametru pozycyjnego / argumentów do skryptu bash.--
forbash
zapewnia, że wszystko, co następuje po nim, jest argumentem, nawet jeśli zaczyna się od znaku-
like,-c
który w przeciwnym razie mógłby zostać zinterpretowany jako opcja bashJeśli chcesz znaleźć typy inne niż ASCII, po prostu zastąp
grep ASCII
je innym typem, na przykładgrep "PDF document, version 1.4"
źródło
Użyj polecenia find, aby wyświetlić listę wszystkich plików, użyj polecenia pliku, aby sprawdzić, czy są tekstem (nie tar, klucz), na koniec użyj polecenia awk, aby przefiltrować i wydrukować wynik.
źródło
Co powiesz na to
źródło
"needle text"
"needl text"
"needle text"
, zostałby znaleziony