मैं पुनरावर्ती अभिलेखागार के माध्यम से कैसे पुनरावृत्ति करूं?


16

मैं पता लगाने की कोशिश कर रहा हूं कि use Test::Versioncpan में कौन से मॉड्यूल हैं । इसलिए मैंने इसे minicpanमिरर करने के लिए इस्तेमाल किया है। मेरी समस्या यह है कि मुझे डाउनलोड किए गए अभिलेखों के माध्यम से पुनरावृति करने की आवश्यकता है, और उन फ़ाइलों को grep करें जो अभिलेखागार में हैं। क्या कोई मुझे बता सकता है कि मैं यह कैसे कर सकता हूं? अधिमानतः एक तरह से जो मुझे बताता है कि संग्रह में कौन सी फ़ाइल है और यह किस लाइन पर है।

(ध्यान दें: वे सभी टारबॉल नहीं हैं कुछ ज़िप फाइलें हैं)

जवाबों:


18

ठीक है, चलो यूनिक्स दर्शन लागू करते हैं। इस कार्य के घटक क्या हैं?

  • पाठ खोज: आपको फ़ाइल में पाठ खोजने के लिए एक उपकरण की आवश्यकता होती है, जैसे कि grep
  • पुनरावर्ती: आपको निर्देशिका ट्री में फ़ाइलों की तलाश में जाने के लिए एक उपकरण की आवश्यकता होती है, जैसे कि find
  • अभिलेखागार: आपको उन्हें पढ़ने के लिए एक उपकरण की आवश्यकता है।

अधिकांश यूनिक्स प्रोग्राम फाइलों पर काम करते हैं। तो संग्रह घटकों पर आसानी से संचालित करने के लिए, आपको उन्हें फ़ाइलों के रूप में एक्सेस करने की आवश्यकता है, दूसरे शब्दों में आपको उन्हें निर्देशिकाओं के रूप में एक्सेस करने की आवश्यकता है।

AVFS फाइल सिस्टम प्रस्तुत फाइल सिस्टम जहां हर संग्रह फ़ाइल के एक दृश्य के /path/to/foo.zipएक निर्देशिका के रूप में पहुँचा जा सकता है ~/.avfs/path/to/foo/zip#। AVFS सबसे आम संग्रह फ़ाइल स्वरूपों में केवल पढ़ने के लिए पहुँच प्रदान करता है।

mountavfs
find ~/.avfs"$PWD" \( -name '*.zip' -o -name '*.tar.gz' -o -name '*.tgz' \) \
     -exec sh -c '
                  find "$0#" -name "*.pm" -exec grep "$1" {\} +
                 ' {} 'Test::Version' \;
fusermount -u ~/.avfs   # optional

स्पष्टीकरण:

  • AVFS फाइलसिस्टम को माउंट करें।
  • संग्रह फ़ाइलों के लिए देखें ~/.avfs$PWD, जो वर्तमान निर्देशिका का AVFS दृश्य है।
  • प्रत्येक संग्रह के लिए, निर्दिष्ट शेल स्निपेट (खोज के लिए $0= संग्रह नाम और $1= पैटर्न के साथ) निष्पादित करें ।
  • $0#संग्रह का निर्देशिका दृश्य है $0
  • {\}बजाय {}जरूरत के मामले में बाहरी findविकल्प बहस के {}अंदर -exec ;(कुछ यह करते हैं, कुछ नहीं)।
  • वैकल्पिक: आखिरकार AVFS फाइलसिस्टम को अनमाउंट करें।

या zsh ≥4.3 में:

mountavfs
grep 'Test::Version' ~/.avfs$PWD/**/*.(tgz|tar.gz|zip)(e\''
     reply=($REPLY\#/**/*.pm(.N))
'\')

स्पष्टीकरण:

  • ~/.avfs$PWD/**/*.(tgz|tar.gz|zip) वर्तमान निर्देशिका और इसके उपनिर्देशिकाओं के AVFS दृश्य में अभिलेखागार से मेल खाता है।
  • PATTERN(e\''CODE'\')पैटर्न के प्रत्येक मैच के लिए कोड लागू होता है। मिलान की गई फ़ाइल का नाम है $REPLYreplyसरणी सेट करना मैच को नामों की सूची में बदल देता है।
  • $REPLY\# संग्रह का निर्देशिका दृश्य है।
  • $REPLY\#/**/*.pm.pmसंग्रह में फ़ाइलों से मेल खाता है ।
  • Nग्लोब क्वालीफायर पैटर्न बनाता है एक खाली सूची का विस्तार अगर कोई मुकाबला नहीं है।

यह माउंट होने की दूसरी तीव्र समस्या पैदा करता है और फिर सभी अभिलेखों को अनमाउंट कर देता है, क्योंकि समस्या का एक हिस्सा यह है कि 22k अभिलेखागार हैं जिनके माध्यम से खोज करने की आवश्यकता है
xenoterracide

@xenoterracide: यह कैसे एक समस्या है? एवीएफएस के साथ, आपके पास एक एकल माउंट बिंदु ( ~/.avfs) है, और प्रत्येक संग्रह तक पहुंच स्वचालित है ( ~/.avfs/path/to/archive.zip\#एवीएफएस फाइल सिस्टम पर एक साधारण निर्देशिका है, माउंट बिंदु नहीं है)। निश्चित रूप से, आपके द्वारा उपयोग किए जाने वाले प्रत्येक संग्रह का मतलब थोड़ा प्रदर्शन हिट है, लेकिन यह समस्या के लिए आंतरिक है।
गिल्स एसओ- बुराई को रोकना '28

@ केवल तथ्य यह है कि अब मुझे गुजरना है और यह पता लगाना है कि पहले उन्हें कैसे माउंट किया जाए, जो कि एक बुरे विचार की तरह लगता है, उन्हें माउंट करने के लिए बेहतर है जैसा कि मैं जाता हूं और खोजे जाने के बाद अनमाउंट करता हूं।
xenoterracide

@xenoterracide: फिर से: नहीं, आपको उन्हें व्यक्तिगत रूप से माउंट करने की आवश्यकता नहीं है। पूर्ण वर्कफ़्लो (यदि आवश्यक हो तो AVFS को स्थापित करने के अलावा) मेरे कोड स्निपेट्स में है।
गिल्स एसओ- बुराई को रोकना '28

@ अच्छी तरह से मैं इस में थोड़ा खोदना होगा ... क्योंकि मैं find: missing argument to -exec'` प्राप्त करता हूं और बहुत से इसे zshzsh: Input/output error: Data-Maker-0.27
xenoterracide

0

ऐसा प्रतीत होता है कि मैं इसे इस तरह से कर सकता हूं

find authors/ -type f -exec zgrep "Test::Version" '{}' +  

हालाँकि, यह परिणाम देता है जैसे:

authors/id/J/JO/JONASBN/Module-Info-File-0.11.tar.gz:Binary file (standard input) matches

जो टारबॉल में बहुत विशिष्ट नहीं है। उम्मीद है कि कोई बेहतर जवाब दे सकता है।


0

चुनौती के लिए धन्यवाद, मैं साथ आया:

#!/bin/bash
#

# tarballs to check in
find authors/ -type f | while read tarball; do

    # get list of files in tarball (not dirs ending in /):
    tar tzf $tarball | grep -v '/$' | while read file; do       

        # get contents of file and look for string
        tar -Ozxf conform.tar.gz $file | grep -q 'Text::Version' && echo "Tar ($tarball) has matching File ($file)"

    done

done

बस अपनी लाइन नंबर की आवश्यकता देखी। वह शायद grep -n के कुछ संयोजन के साथ काम कर सकता है और लाइन नंबर पर कब्जा करने के लिए जागता है। हमेशा की तरह स्ट्रेच को सूचीबद्ध करने के लिए grep -H जितना सरल नहीं हो सकता है, इसलिए अधिक लाइनों की आवश्यकता हो सकती है।
काइल स्मिथ

मेरे सिस्टम पर चलने पर त्रुटियां, अनंत दोहराया:tar (child): conform.tar.gz: Cannot open: No such file or directory tar (child): Error is not recoverable: exiting now tar: Child returned status 2 tar: Error is not recoverable: exiting now
xenoterracide

यह भी मुझे महसूस नहीं हुआ जब मैंने पहली बार यह पोस्ट किया था कि cpan पर कुछ अभिलेखागार ज़िप फाइलें हैं।
xenoterracide

हम्म, मैंने केवल .tar.gz फ़ाइलों की संरचना के साथ परीक्षण किया - इसे फ़ाइल प्रकार के आधार पर उचित कार्रवाई करने के लिए और अधिक मजबूत बनाया जा सकता है, लेकिन यह एक सभ्य प्रारंभिक बिंदु देना चाहिए।
काइल स्मिथ

0

शायद मेरा जवाब किसी के लिए उपयोगी होगा:

#!/bin/bash

findpath=$(echo $1 | sed -r 's|(.*[^/]$)|\1/|')

# tarballs to check in
find $findpath -type f | while read tarball; do

    # get list of files in tarball (not dirs ending in /):
    if [ -n "$(file --mime-type $tarball | grep -e "application/jar")" ]; then

        jar tf $tarball | grep -v '/$' | while read file; do
            # get contents of file and look for string
            grepout=$(unzip -q -c $tarball $file | grep $3 -e "$2")

            if [ -n "$grepout" ]; then
                echo "*** $tarball has matching file ($file):"
                echo $grepout
            fi

        done

    elif tar -tf $tarball 2>/dev/null; then

        tar -tf $tarball | grep -v '/$' | while read file; do
            # get contents of file and look for string
            grepout=$(unzip -q -c $tarball $file | grep $3 -e "$2")

            if [ -n "$grepout" ]; then
                echo "*** $tarball has matching file ($file):"
                echo $grepout
            fi

        done

    else
        file=""
        grepout=$(grep $3 -e "$2" $tarball)

        if [ -n "$grepout" ]; then
            echo "*** $tarball has matching:"
            echo $grepout
        fi

    fi

done

0

स्थापित करने के बाद p7zip-*आप ऐसा करने में सक्षम हैं:

ls | xargs -I {} 7z l {} | grep whatever | less

आपको lsपहले पाइप से पहले उपयोग करने की आवश्यकता नहीं है , जो भी संकुचित फ़ाइलों की सूची काम करेगी। अंतिम lessकेवल संपीड़ित संग्रह के अंदर सूची जीवन का पथ प्रदर्शित करेगा, लेकिन इसका नाम नहीं।


0

सभी आवश्यक फ़ाइलों को खोजने के लिए खोज का उपयोग करें, और संपीड़ित फ़ाइलों को देखने के लिए उस zgrep:

find <folder> -type f -name "<search criteria[*gz,*bz...]>" -execdir zgrep -in "<grep expression>" '{}' ';'

हालांकि टैरबॉल पर यह परीक्षण नहीं किया

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