2012-10-23 12 views
5

मेरे पास एक टैर संग्रह है जो बहुत बड़ा ~ 5 जीबी है।डिस्क स्पेस भरने के बिना टैर आर्काइव में फ़ाइलों में पैटर्न के लिए grep कैसे करें

मैं संग्रह में सभी फ़ाइलों पर एक पैटर्न के लिए grep करना चाहता हूं (और पैटर्न में फ़ाइल का नाम भी मुद्रित करता हूं) लेकिन संग्रह को निकालने से मेरी डिस्क स्पेस भरना नहीं चाहता।

वैसे भी मैं ऐसा कर सकता हूं?

मैं इन कोशिश की, लेकिन यह मेरे फ़ाइल नाम है कि पैटर्न होते हैं, बस मिलान लाइनों नहीं देता:

tar -O -xf test.tar.gz | grep 'this' 
tar -xf test.tar.gz --to-command='grep awesome' 

इसके अलावा जहां टार की इस सुविधा से प्रलेखित है? टैर xf test.tar $ FILE

+2

http://stackoverflow.com/questions/2407111/performing-grep-operation-in-tar-files-with-out-extracting –

+0

@OpDeCirkel कहाँ टैर दस्तावेज की यह विशेषता है? tar xf test.tar $ FILE – abc

+0

उदाहरण अनुभाग (अंतिम उदाहरण) में मिला: http://unixhelp.ed.ac.uk/CGI/man-cgi?tar –

उत्तर

6

यहाँ इस पर मेरी ले है

  • while read filename; do - यह एक पाश है ...
  • tar -xOf file.tar "$filename" - इस प्रत्येक फ़ाइल निकालता है ...
  • | grep 'pattern' - यहां आप अपना पैटर्न डालते हैं ...
  • | sed "s|^|$filename:|"; - फ़ाइल नाम प्रीपेड करें, तो यह grep जैसा दिखता है। नमक स्वादअनुसार।
  • done < <(tar -tf file.tar | grep -v '/$') - लूप समाप्त करें, फ़ाइलों की सूची प्राप्त करें ताकि आपके while read पर फीड हो सके।

एक प्रावधान: यदि आपके पास अपने फ़ाइल नामों में OR बार (|) हैं तो यह तोड़ता है।

हम्म।वास्तव में, यह एक अच्छी छोटी बैश समारोह, जो आप अपने .bashrc फाइल करने के लिए जोड़ सकते हैं बनाता है:

targrep() { 

    local taropt="" 

    if [[ ! -f "$2" ]]; then 
    echo "Usage: targrep pattern file ..." 
    fi 

    while [[ -n "$2" ]]; do  

    if [[ ! -f "$2" ]]; then 
     echo "targrep: $2: No such file" >&2 
    fi 

    case "$2" in 
     *.tar.gz) taropt="-z" ;; 
     *) taropt="" ;; 
    esac 

    while read filename; do 
     tar $taropt -xOf "$2" \ 
     | grep "$1" \ 
     | sed "s|^|$filename:|"; 
    done < <(tar $taropt -tf $2 | grep -v '/$') 

    shift 

    done 
} 
+0

मैं इतने पर धन्यवाद नफरत है, लेकिन यह एक सच में मुझे बाहर मदद की - THX (: – drevicko

3

यहां एक बैश फ़ंक्शन है जो आपके लिए काम कर सकता है। अपने ~/.bashrc

targrep() { 
    for i in $(tar -tzf "$1"); do 
     results=$(tar -Oxzf "$1" "$i" | grep --label="$i" -H "$2") 
     echo "$results" 
    done 
} 

प्रयोग के लिए निम्न जोड़ें:

targrep archive.tar.gz "pattern" 
+0

यह काम नहीं करता है। यह फ़ाइल नाम के रूप में प्रिंट (मानक इनपुट)। मैंने -एल और -एच के साथ प्रयास किया। – abc

+0

@abc: क्या यह संस्करण आपके लिए बेहतर काम करता है? – Steve

+1

दोह, मैंने अपना लिखा था इससे पहले कि मैंने आपके बैश फ़ंक्शन को नहीं देखा था। और तुम्हारा से मेरा अच्छा है। :-) ** + 1 **। (अब जब मैं जांचता हूं, ऐसा लगता है कि फ्रीबीएसडी का टैर स्वचालित रूप से gzipped फ़ाइलों को पहचानता है, इसलिए मेरी फ़ाइल नाम पहचान अनावश्यक हो सकती है।) – ghoti

0

प्रयास करें:

tar tvf name_of_file |grep --regex="pattern" 

टी विकल्प फ़ाइलों को निकालने के बिना टार फ़ाइल का परीक्षण होगा। वी verbose है और एफ प्रिंट वह filenames। यह आपको काफी हार्ड डिस्क स्थान बचा लेना चाहिए।

+0

यह सही नहीं है। क्या आपने पोस्ट करने से पहले यह कोशिश की है? – abc

+1

इसके साथ क्या गलत है, @ एबीसी? यह फाइलों को निकाला नहीं है; यह मानक आउटपुट पर फ़ाइल नाम प्राप्त करता है, और उनके लिए greps। आपको क्या परिणाम मिला? या यह समस्या है कि आप फ़ाइलों के नाम प्राप्त करना चाहते हैं जिनमें फ़ाइल निकालने के बिना फ़ाइल के शरीर में पैटर्न शामिल है ... यह कठिन है, लेकिन सवाल में स्पष्ट रूप से वर्णित नहीं है। –

+0

@ जोनाथन लेफ्लर ठीक है। – abc

1

यह अविश्वसनीय रूप से हैकी है, लेकिन आप प्रत्येक फ़ाइल को निकालने और निकालने के लिए टैर के -v विकल्प का दुरुपयोग कर सकते हैं।

while read filename; do tar -xOf file.tar "$filename" | grep 'pattern' | sed "s|^|$filename:|"; done < <(tar -tf file.tar | grep -v '/$') 

विवरण के लिए बाहर टूटी:

grep_and_delete() { 
    if [ -n "$1" -a -f "$1" ]; then 
    grep -H 'this' -- "$1" </dev/null 
    rm -f -- "$1" </dev/null 
    fi 
} 
mkdir tmp; cd tmp 
tar -xvzf test.tar.gz | (
    prev='' 
    while read pathname; do 
    grep_and_delete "$prev" 
    prev="$pathname" 
    done 
    grep_and_delete "$prev" 
) 
+0

http://stackoverflow.com/questions/2407111/performing-grep-operation-in-tar-files-with-out-extracting – abc

+0

क्योंकि यह केवल एक बार '.tar.gz' फ़ाइल संपीड़ित इस तरह तेजी से होता है। – aecolley

1
tar -tf test.tar.gz | grep -v '/$'| \ 
xargs -n 1 -I _ \ 
sh -c 'tar -xOf test.tar.gz _|grep -q <YOUR SEARCH PATTERN> && echo _' 
+0

क्या आप मूल पोस्ट की टिप्पणी में मेरे प्रश्न का उत्तर दे सकते हैं? – abc

+0

@ एबीसी, अगर यह आपके प्रश्न का हिस्सा है, तो आप [इसे अपने प्रश्न में क्यों जोड़ें] (http://stackoverflow.com/posts/13041068/edit) क्यों नहीं? – Graham

9

कोई भी नहीं की तरह लगता है इस सरल समाधान पोस्ट किया है कि प्रक्रियाओं संग्रह केवल एक बार:

tar xzf archive.tgz --to-command \ 
    'grep --label="$TAR_FILENAME" -H PATTERN ; true' 

यहां tar एक चर में प्रत्येक फ़ाइल का नाम पास करता है (the docs देखें) और इसका उपयोग प्रत्येक मैच के साथ प्रिंट करने के लिए grep द्वारा किया जाता है। true भी जोड़ा गया है ताकि tar उन फ़ाइलों को निकालने में विफल होने की शिकायत नहीं करता है जो मेल नहीं खाते हैं।

+1

सर्वश्रेष्ठ उत्तर, पूरी तरह से काम करता है और के रूप में द्वारा टार – Matt

+0

इरादा '; TRUE' मेरे लिए काम नहीं कर रहा है, उन लोगों के लिए तर्क के रूप में पारित किया जा रहा है। और zsh' '' TRUE' फाइल या निर्देशिका नहीं किया जा रहा –

+0

@DanielH कौन सा खोल प्रयोग कर रहे हैं यह प्रभावित कर सकता है आदेश पार्स और रन है –

संबंधित मुद्दे