मैं .gz फ़ाइलों के माध्यम से पुनरावर्ती कैसे प्राप्त करूं?


135

मैं अपने gmail संदेशों को नियमित रूप से डाउनलोड करने के लिए एक स्क्रिप्ट का उपयोग कर रहा हूं जो कच्चे .eml को .gz फ़ाइलों में संपीड़ित करता है। स्क्रिप्ट प्रत्येक दिन के लिए एक फ़ोल्डर बनाता है, और फिर प्रत्येक संदेश को अपनी फ़ाइल में संपीड़ित करता है।

मैं एक "स्ट्रिंग" के लिए इस संग्रह के माध्यम से खोज करने का एक तरीका चाहूंगा।

अकेले ग्रेप इसे करने के लिए प्रकट नहीं होता है। मैंने SearchMonkey भी आज़माया।


16
उपयोग zgrep:zgrep - search possibly compressed files for a regular expression
अर्कादिअस ड्रेब्ज़क

जवाबों:


141

यदि आप वर्तमान निर्देशिका में सभी .eml.gz फ़ाइलों में पुनरावृत्ति करना चाहते हैं, तो आप उपयोग कर सकते हैं:

find . -name \*.eml.gz -print0 | xargs -0 zgrep "STRING"

आपको पहले बचना होगा *ताकि खोल इसकी व्याख्या न करे। -print0बताता है कि प्रत्येक फ़ाइल को खोजने के बाद एक अशक्त चरित्र को प्रिंट करना; xargs -0मानक इनपुट से पढ़ता है और प्रत्येक फ़ाइल के लिए इसके बाद कमांड चलाता है; zgrepकी तरह काम करता है grep, लेकिन पहले फ़ाइल को खोल देता है।


2
'-प्रिंट0' और '-0' अनिवार्य नहीं हैं। xargs डिफ़ॉल्ट रूप से '\ n' का उपयोग करता है।
Jaime M.

1
यदि मार्ग में स्थान वर्ण हो सकते हैं तो वे आवश्यक हैं; जटिलता का उपयोग न करने के अलावा और कोई कारण नहीं है।
डैनियल ग्रिस्कॉम

2
zgrepवास्तव में grepअसम्पीडित फ़ाइलों पर चलाने की तुलना में तेज़ लगता है । यह होना चाहिए क्योंकि संपीड़ित फ़ाइलों को पढ़ा जा सकता है HD और एक से असंपीड़ित फ़ाइल को पढ़ने की तुलना में तेजी से विघटित HD।
गेरिमिया

@JaimeM। डिफ़ॉल्ट रूप से रिक्त स्थान (व्हाट्सएप) xargsका उपयोग करता है । निश्चित रूप से, फ़ाइलों में लगभग कभी भी नई लाइनें नहीं होती हैं, लेकिन रिक्त स्थान अनसुना नहीं होते हैं (भले ही अधिकांश यूनिक्स प्रकार उन पर फेंके गए हों)। उस ने कहा, आप व्हॉट्सएप के बारे में और भी आसानी से चिंता किए बिना इसे सरल बना सकते हैं: कि प्रति-लॉन्च के समान कई तर्क मिलते हैं , / की सुरक्षा , और सभी बिना अतिरिक्त प्रक्रिया के लॉन्च और पाइपिंग के ओवरहेड और काफी संक्षिप्त रूप से। के साथ POSIX निर्दिष्ट है, इसलिए यह मेरी जानकारी के लिए अधिकांश अर्ध-हाल ही में UNIX जैसी प्रणालियों पर होना चाहिए। find . -name '*.eml.gz' -exec zgrep "STRING" {} +xargs-print0-0-exec+
शैडो रेंजर

@Jared एक वाइल्डकार्ड खोज करने का एक तरीका है जो केवल फ़ाइल पैटर्न की शुरुआत को जानना है? उदाहरण के लिए, मेरे पास .gz फाइलें हैं जिनके पास दिनांक / समय टिकट हैं। ABCLog04_18_18_2_21.gz क्या एबीसी * के साथ शुरू होने वाली फ़ाइलों के लिए पुनरावर्ती रूप से देखने का एक तरीका है। मैंने \*.eml.gzआपके उदाहरण के साथ ऊपर की जगह बदलने की कोशिश की ABCLog*और फ़ाइल प्रारूप के बारे में एक त्रुटि प्राप्त की।: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]
DevelopingDeveloper

68

यहाँ बहुत भ्रम है क्योंकि वहाँ सिर्फ एक नहीं है zgrep। मैं अपने सिस्टम पर दो संस्करण हैं, zgrepसे gzipऔर zgrepसे zutils। पूर्व केवल एक आवरण स्क्रिप्ट है जो कॉल करता है gzip -cdfq। यह -r, --recursiveस्विच का समर्थन नहीं करता है । 1
उत्तरार्द्ध एक c++कार्यक्रम है और यह विकल्प का समर्थन करता -r, --recursiveहै।
रनिंग zgrep --version | head -n 1से पता चलेगा कि कौन सा (यदि कोई है) डिफ़ॉल्ट है:

zgrep (gzip) 1.6

आवरण लिपि है,

zgrep (zutils) 1.3

है cppनिष्पादन।
यदि आपके पास बाद है तो आप दौड़ सकते हैं:

zgrep 'pattern' -r --format=gz /path/to/dir

वैसे भी, जैसा कि सुझाव दिया गया है, find+ के zgrepसंस्करण के साथ समान रूप से अच्छी तरह से काम करेगा zgrep:

find /path/to/dir -name '*.gz' -exec zgrep -- 'pattern' {} +

यदि zgrepआपके सिस्टम से गायब है (अत्यधिक संभावना नहीं है) तो आप इसके साथ प्रयास कर सकते हैं:

find /path/to/dir -name '*.gz' -exec sh -c 'gzip -cd "$0" | grep -- "pattern"' {} \;

लेकिन एक बड़ा नकारात्मक पहलू है: आपको पता नहीं चलेगा कि मैच कहाँ हैं क्योंकि मिलान लाइनों के लिए कोई फ़ाइल नाम नहीं है।


1: क्योंकि यह समस्याग्रस्त होगा


1
यदि zgrepzutils उपलब्ध नहीं है, तो आप इसे उबंटू में स्थापित कर सकते हैं sudo apt-get install zutils
थेरैल्मव जूल 27'15

1
@Therealmarv से जारी है ... और फिर उबंटू जिप्पी एक के बजाय zutils zgrep का उपयोग करेगा। तब -आर काम करता है!
एलिजा लिन

क्या फ़ाइल का लाइन नंबर प्रिंट करने का एक तरीका है जिससे पैटर्न का मिलान किया जाता है?
डॉगएटडॉग

@DogEatDog - जैसे grep -n, zgrep -nलाइन नं। प्रिंट करेगा यह मैनुअल में है ...
don_crissti

7

agका एक संस्करण है grep, जिसमें कुछ अच्छी अतिरिक्त विशेषताएं हैं।

  • संकुचित फ़ाइलों के लिए -z विकल्प है,
  • ack की कई विशेषताएं हैं।
  • यह तेज़ है

इसलिए:

ag -r -z your-pattern-goes-here   folder

यदि स्थापित नहीं है,

apt-get install silversearcher-ag   (debian and friends)
yum install the_silver_searcher     (fedora)
brew install the_silver_searcher    (mac)

1
मुझे ag: truncated file: Successइसका परिणाम मिलता है । मुझे कोई अन्य ध्वज जोड़ना चाहिए?
यार

4

अकेले पुनरावृत्ति आसान है:

   -r, --recursive
          Read all files  under  each  directory,  recursively,  following
          symbolic  links  only  if they are on the command line.  This is
          equivalent to the -d recurse option.

   -R, --dereference-recursive
          Read all files under each directory,  recursively.   Follow  all
          symbolic links, unlike -r.

हालाँकि, संकुचित फ़ाइलों के लिए आपको कुछ चाहिए:

shopt globstar 
for file in /path/to/directory/**/*gz; do zcat ""$file" | grep pattern; done

path/to/directory प्रत्येक दिन के लिए उपनिर्देशिका वाले मूल निर्देशिका होनी चाहिए।


zgrepस्पष्ट उत्तर है लेकिन, दुर्भाग्य से, यह -rध्वज का समर्थन नहीं करता है । से man zgrep:

ये grep विकल्प zgrep को एक त्रुटि कोड के साथ समाप्त करने का कारण बनेंगे: (- [d rR zZ] - - * * --exc * | --inc * * --rec * | --nu *)।


3

यदि आपके सिस्टम में zgrep है, तो आप बस कर सकते हैं

zgrep -irs your-pattern-goes-here the-folder-to-search-goes-here/

यदि आपके सिस्टम में zgrep नहीं है, तो आप प्रत्येक फ़ाइल के खिलाफ zcat और grep चलाने के लिए खोज कमांड का उपयोग कर सकते हैं :

find the-folder-to-search-goes-here/ -name '*.gz' \ -exec sh -c 'echo "Searching {}" ; zcat "{}" | grep your-pattern-goes-here ' \;


इस पर मुझे माफ़ कर दो ... के माध्यम से खोज की जाने वाली फाइलें गहरी परतों की एक जोड़ी हैं। ~ / gmvault-db / db / 2015-02 में संग्रहीत प्रत्येक माह के लिए एक फ़ोल्डर होता है, और उसके बाद उस माह के लिए .gz फ़ाइलें संग्रहीत की जाती हैं। अगर मैं उस पूरे पेड़ के भीतर .mil की खोज करूं, तो क्या मैं ऐसा करूंगा? find ~ / gmvault-db / db /name '* * .gz' \ -exec sh -c 'echo "Searching {}"; zcat "{}" | grep .mil '\;
केंडोर

1
यह ठीक है - "आर" इन-आरएस ज़ीर्रेप को पुनरावर्ती खोज करने का कारण बनेगा। खोज आदेश डिफ़ॉल्ट रूप से पुनरावर्ती रूप से संचालित होता है, इसलिए .gz में समाप्त होने वाली किसी भी फ़ाइल को zcatted और grep में पारित किया जाएगा। (और {} खोज की जाने वाली फ़ाइल के सापेक्ष पथ में विस्तारित की जाएगी)। इसलिए जब आप एक हिट प्राप्त करते हैं, तो यह पूर्ववर्ती होगा Searching ~/gmvault-db/db/2015-02/03/whatever.gz
नैट से कलामाज़ू

यहाँ मुझे जो मिलता है वह है: खोज: "पथों की पूर्ववर्ती अभिव्यक्ति होनी चाहिए: -exec" यहाँ मैंने जो कमांड प्रयोग किया है: ~ ~ / gmvault-db / db / -name '* * .gz' \ -exec sh -c-echo "खोज" } "; zcat "{}" | grep .mil '\;
केंडोर

'* .gz' और -exec के बीच के बैकस्लैश को बाहर निकालें।
कलामज़ू

4
zgrep-rकिसी कारण से झंडा नहीं लेंगे । इसमें उल्लेख है man zgrep(मेरा उत्तर भी देखें)।
terdon

0

xzgrep -l "string" ./*/*.eml.gz

xzgrep zgrep बर्तनों का एक व्युत्पन्न है (कम / बिन / xzgrep)

मैन पेज से:

xzgrep उन फाइलों पर grep (1) को आमंत्रित करता है जो या तो xz (1), lzma (1), gzip (1), bzip2 (1), या lzop (1) के साथ असम्पीडित या संकुचित हो सकती हैं। निर्दिष्ट सभी विकल्प सीधे grep (1) को पास किए जाते हैं।

-एल मेल खाते का नाम प्रिंट करें

- पुनरावृत्ति के लिए आरआर काम नहीं करेगा क्योंकि यह विशेष रूप से स्क्रिप्ट में निषिद्ध है, हालांकि सरल शेल ग्लोबिंग हमें वहां प्राप्त करना चाहिए

./*/*.eml.gz

एक सापेक्ष पथ से जहां / .today/sample.eml.gz, उस के सभी उदाहरणों पर मेल खाते हैं, जो शेल में हमारी सापेक्ष स्थिति से एक स्तर नीचे हैं, जो ".eml.gz" के साथ समाप्त होता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.