Mam katalog zawierający około 26 000 plików i muszę grep w tych wszystkich plikach. Problem polega na tym, że potrzebuję go tak szybko, jak to możliwe, więc nie jest idealnym skryptem, w którym grep pobierze nazwę jednego pliku z polecenia find i zapisze dopasowania do pliku. Przed wydaniem „zbyt długiej listy argumentów” zajęło około 2 minut grep we wszystkich tych plikach. Wszelkie pomysły, jak to zrobić? edycja: istnieje skrypt, który cały czas tworzy nowe pliki, więc nie można umieścić wszystkich plików w różnych katalogach.
files
grep
performance
użytkownik2778979
źródło
źródło
find
zxargs
lubgrep -R
Odpowiedzi:
Z
find
:(
-type f
jest wyszukiwanie tylko w zwykłych plikach (z wyłączeniem również dowiązań symbolicznych, nawet jeśli wskazują one na zwykłe pliki). Jeśli chcesz wyszukiwać w dowolnym typie plików oprócz katalogów (ale uważaj, istnieją pewne typy plików, takie jak fifos lub / dev / zero, które na ogół nie chcesz czytać), zamień-type f
na GNU! -xtype d
(-xtype d
pasuje do plików typu katalog po rozpoznaniu dowiązania symbolicznego)).Z GNU
grep
:(ale uważaj, jeśli nie masz najnowszej wersji GNU grep, która będzie podążać za dowiązaniami symbolicznymi podczas schodzenia do katalogów). Nieregularne pliki nie będą wyszukiwane, chyba że dodasz
-D read
opcję. Najnowsze wersje GNUgrep
nadal nie będą jednak wyszukiwać wewnątrz dowiązań symbolicznych.Bardzo stare wersje GNU
find
nie obsługiwały standardowej{} +
składni, ale tam możesz użyć niestandardowej:Występy prawdopodobnie będą związane z operacjami wejścia / wyjścia. To czas na wyszukiwanie byłby czasem potrzebnym do odczytania wszystkich danych z pamięci.
Jeśli dane znajdują się na nadmiarowej macierzy dyskowej, odczytywanie kilku plików jednocześnie może poprawić wydajność (i w przeciwnym razie może je pogorszyć). Jeśli wydajność nie jest związana z operacjami we / wy (ponieważ na przykład wszystkie dane znajdują się w pamięci podręcznej) i masz wiele procesorów,
greps
może również pomóc współbieżność . Można to zrobić z GNUxargs
„s-P
opcja.Na przykład, jeśli dane znajdują się w macierzy RAID1 z 3 dyskami lub jeśli dane znajdują się w pamięci podręcznej i masz 3 procesory, których czas oszczędzić:
(tutaj za pomocą
-n1000
odradzania nowegogrep
co 1000 plików, do 3 równolegle działających jednocześnie).Należy jednak pamiętać, że jeśli dane wyjściowe
grep
zostaną przekierowane, otrzymamy źle przeplecione dane wyjściowe z 3grep
procesów, w którym to przypadku możesz chcieć uruchomić je jako:(w najnowszym systemie GNU lub FreeBSD) lub użyj
--line-buffered
opcji GNUgrep
.Jeśli
pattern
jest to ciąg stały, dodanie-F
opcji może poprawić sprawy.Jeśli nie są to dane wielobajtowe lub jeśli chodzi o dopasowanie tego wzorca, nie ma znaczenia, czy dane są znakiem wielobajtowym, czy nie:
może znacznie poprawić wydajność.
Jeśli często przeprowadzasz takie wyszukiwania, możesz zindeksować swoje dane przy użyciu jednej z wielu wyszukiwarek.
źródło
26000 plików w jednym katalogu to dużo dla większości systemów plików. Prawdopodobnie znaczna część czasu zajmuje czytanie tego dużego katalogu. Rozważ podzielenie go na mniejsze katalogi zawierające tylko kilkaset plików.
Połączenia
find
nie mogą wyjaśnić słabej wydajności, chyba że zrobisz to źle. Jest to szybki sposób na przejrzenie katalogu i upewnienie się, że nie ryzykujesz próby wykonania zbyt długiego wiersza poleceń. Upewnij się, że używasz tego-exec grep PATTERN {} +
, który pakuje tyle plików, ile może na wywołanie polecenia, a nie-exec grep PATTERN {} \;
, który wykonuje sięgrep
raz na plik: wykonanie polecenia raz na plik może być znacznie wolniejsze.źródło
Jeśli musisz grepować WSZYSTKIE pliki wiele razy (jak powiedziałeś, uruchamiając skrypt) sugerowałbym zajrzenie do dysków RAM, skopiowanie wszystkich plików tam, a następnie wielokrotne grepowanie plików, to przyspieszy twoje wyszukiwanie o współczynnik co najmniej 100x.
Potrzebujesz tylko wystarczającej ilości pamięci RAM. W przeciwnym razie powinieneś zajrzeć do indeksowania plików, np. do bazy danych Lucene lub nosql, a następnie uruchamianie zapytań w tej sprawie.
źródło
grep
. Jest też taki punkt, że: „istnieje skrypt, który cały czas tworzy nowe pliki, więc nie można umieszczać wszystkich plików w różnych katalogach”.Wszystkie pliki w katalogu
z rekurencyjnie
źródło
.
zamiast niego*
).*
wyklucza pliki kropkowe (choć z opcją -R, a nie te w katalogach cyklicznych). -R w przeciwieństwie do -r podąża za dowiązaniami symbolicznymi nawet w najnowszych wersjach GNU grep. Będziesz także mieć problem z plikami w bieżącym katalogu, których nazwa zaczyna się na-