Korzystam ze skryptu, aby regularnie pobierać wiadomości Gmaila, które kompresują nieprzetworzony plik .eml do plików .gz. Skrypt tworzy folder na każdy dzień, a następnie kompresuje każdą wiadomość do własnego pliku.
Chciałbym znaleźć sposób na przeszukanie tego archiwum pod kątem „ciągu”.
Wydaje się, że sam Grep tego nie robi. Próbowałem także SearchMonkey.
zgrep
:zgrep - search possibly compressed files for a regular expression
Odpowiedzi:
Jeśli chcesz rekurencyjnie grepować we wszystkich plikach .eml.gz w bieżącym katalogu, możesz użyć:
Musisz uciec od pierwszego,
*
aby powłoka go nie interpretowała.-print0
każe programowi find wypisać znak zerowy po każdym znalezionym pliku;xargs -0
odczytuje ze standardowego wejścia i uruchamia polecenie po nim dla każdego pliku;zgrep
działa jakgrep
, ale najpierw rozpakowuje plik.źródło
zgrep
faktycznie wydaje się szybszy niżgrep
uruchamianie na nieskompresowanych plikach. Musi tak być, ponieważ skompresowane pliki można odczytać z dysku twardego i rozpakować szybciej niż odczytanie nieskompresowanego pliku z dysku twardego.xargs
wykorzystuje wykrojów (spacje) domyślnie. Jasne, pliki prawie nigdy nie mają w sobie nowych linii, ale spacje nie są niespotykane (nawet jeśli większość typów UNIXy się na nich marszczy). To powiedziawszy, możesz uprościć, nie martwiąc się o spacje jeszcze łatwiej:find . -name '*.eml.gz' -exec zgrep "STRING" {} +
to dostaje tyle samo argumentów na uruchomieniexargs
, bezpieczeństwo-print0
/-0
, a wszystko to bez dodatkowych kosztów uruchomienia procesu i potokowania, i dość zwięźle.-exec
z+
jest określony w POSIX, więc powinien być w większości nowszych systemów podobnych do UNIX, o ile mi wiadomo.ABCLog04_18_18_2_21.gz
Czy istnieje sposób na rekurencyjne wyszukiwanie plików zaczynających się na ABC *. Próbowałem zastąpić\*.eml.gz
w powyższym przykładzieABCLog*
komunikat o błędzie dotyczący formatu pliku .:find: paths must precede expression: ABCLog-2018-03-12-10-16-1.log.gz Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]
Jest tu wiele zamieszania, ponieważ nie ma tylko jednego
zgrep
. Mam dwie wersje w moim systemie,zgrep
odgzip
izgrep
odzutils
. Ten pierwszy jest tylko skryptem otoki, który wywołujegzip -cdfq
. Nie obsługuje-r, --recursive
przełącznika. 1Ten ostatni jest
c++
programem i obsługuje tę-r, --recursive
opcję.Uruchomienie
zgrep --version | head -n 1
ujawni, który z nich (jeśli w ogóle) jest domyślny:to skrypt otoki,
jest
cpp
plikiem wykonywalnym.Jeśli masz ten drugi, możesz uruchomić:
W każdym razie, zgodnie z sugestią,
find
+zgrep
będzie działać równie dobrze z każdą wersjązgrep
:Jeśli
zgrep
brakuje w twoim systemie (bardzo mało prawdopodobne), możesz spróbować z:ale ma to poważną wadę: nie będziesz wiedział, gdzie są dopasowania, ponieważ do pasujących wierszy nie ma nazwy pliku.
1: ponieważ byłoby to problematyczne
źródło
zgrep
z Zutils nie jest dostępny, możesz zainstalować go w Ubuntu za pomocąsudo apt-get install zutils
.grep -n
,zgrep -n
wydrukuje nr linii. Jest w instrukcji ...ag
jest wariantemgrep
z kilkoma ładnymi dodatkowymi funkcjami.Więc:
Jeśli nie jest zainstalowany,
źródło
ag: truncated file: Success
w rezultacie. Jakąkolwiek inną flagę powinienem dodać?Sama rekursja jest łatwa:
Jednak w przypadku plików skompresowanych potrzebujesz czegoś takiego:
path/to/directory
powinien być katalogiem nadrzędnym, który zawiera podkatalogi na każdy dzień.zgrep
jest oczywistą odpowiedzią, ale niestety nie obsługuje-r
flagi. Odman zgrep
:źródło
Jeśli twój system ma zgrep, możesz po prostu
zgrep -irs your-pattern-goes-here the-folder-to-search-goes-here/
Jeśli twój system nie ma zgrep, możesz użyć polecenia find, aby uruchomić zcat i grep dla każdego pliku w następujący sposób:
find the-folder-to-search-goes-here/ -name '*.gz' \ -exec sh -c 'echo "Searching {}" ; zcat "{}" | grep your-pattern-goes-here ' \;
źródło
Searching ~/gmvault-db/db/2015-02/03/whatever.gz
zgrep
-r
z jakiegoś powodu nie weźmie flagi. To jest wzmianka wman zgrep
(patrz także moja odpowiedź).xzgrep jest pochodną narzędzia zgrep (mniej / bin / xzgrep)
Ze strony Man:
-l wypisz pasującą nazwę pliku
-R rekurencja nie będzie działać, ponieważ jest to wyraźnie zabronione w skrypcie, jednak proste globowanie powłoki powinno nas tam doprowadzić
ze ścieżki względnej, gdzie ./today/sample.eml.gz, dopasuj we wszystkich instancjach o jeden poziom poniżej naszej względnej pozycji w powłoce, która kończy się na „.eml.gz”
źródło