सभी फाइलों को देखने के लिए बिल्ली को खोजने के लिए फाइलों की सूची कैसे वापस करें


204

मैं findएक फाइल कर रहा हूं और फिर फाइलों की एक सूची प्राप्त कर रहा हूं । मैं इसे अन्य उपयोगिता की तरह कैसे पाइप कर सकता हूं cat(ताकि बिल्ली उन सभी फ़ाइलों की सामग्री को प्रदर्शित करे) और मूल रूप grepसे इन फ़ाइलों से कुछ की आवश्यकता है ।

जवाबों:


340
  1. किसी अन्य प्रक्रिया के लिए पाइपिंग (हालाँकि यह वह नहीं है जो आपने कहा था कि आप क्या करने की कोशिश कर रहे हैं):

    command1 | command2
    

    यह कमांड 1 के आउटपुट को कमांड 2 के इनपुट के रूप में भेजेगा

  2. -execfindइस पर (यह वही करेगा जो आप करना चाहते हैं - लेकिन यह विशिष्ट है find)

    find . -name '*.foo' -exec cat {} \;
    

    (सब कुछ के बीच में हैं findऔर -execआप पहले से ही उपयोग कर रहे हैं की भविष्यवाणी कर रहे हैं। {}कमांड में पाया गया विशेष फ़ाइल स्थानापन्न कर देगा ( cat {}इस मामले में), कमांड \;को समाप्त करने के लिए है -exec।)

  3. एक प्रक्रिया के आउटपुट को कमांड लाइन के तर्क के रूप में दूसरी प्रक्रिया में भेजें

    command2 `command1`
    

    उदाहरण के लिए:

    cat `find . -name '*.foo' -print`
    

    (ध्यान दें कि ये BACK-QUOTES नियमित उद्धरण नहीं हैं (मेरे कीबोर्ड पर tilde ~ के तहत)।) यह कमांड लाइन के तर्कों के रूप command1में आउटपुट भेजेगा command2। ध्यान दें कि रिक्त स्थान (newlines, आदि) वाले फ़ाइल नाम अलग-अलग तर्कों में टूट जाएंगे, हालाँकि।


2
कैट find -name '*.foo' -printने मेरे लिए बहुत अच्छा काम किया ... धन्यवाद
देवांग कामदार

Backquotes महान काम करते हैं और अधिक सामान्यीकृत होते हैं, आप इसका उपयोग किसी फ़ाइल की फ़ाइलों की सूची के साथ-साथ बिल्ली से भी कर सकते हैं।
हज़ोक

11
ध्यान दें कि आधुनिक संस्करण findआपको लिखने की अनुमति देते हैं: find . -name '*.foo' -exec cat {} +जहां +इंगित करता है कि findएक एकल कमांड आह्वान में सुविधाजनक के रूप में कई फ़ाइल नामों के रूप में समूह होना चाहिए। यह काफी उपयोगी है (यह बिना किसी का सहारा लिए -print0और फ़ाइल नामों में रिक्त स्थान आदि से संबंधित है xargs -0)।
जोनाथन लेफ़लर

18
Unmentioned:find . -name '*.foo' | xargs cat
stewSquared

3
बस @stewSquared के उत्तर को जोड़ने के लिए: फ़ाइलों में सभी पंक्तियों को खोजने के लिए जिसमें एक निश्चित स्ट्रिंग होती है, करेंfind . -name '*.foo' | xargs cat | grep string
Bim

84

आधुनिक संस्करण

POSIX 2008 ने +मार्कर को जोड़ा findजिसका अर्थ है कि यह अब स्वचालित रूप से कई फाइलों को एक कमांड कमांड में उचित रूप से समूह xargsकरता है, बहुत पसंद करता है, लेकिन कई फायदे के साथ:

  1. आपको फ़ाइल नामों में विषम वर्णों के बारे में चिंता करने की आवश्यकता नहीं है।
  2. आपको शून्य फ़ाइल नामों के साथ कमांड को लागू करने के बारे में चिंता करने की ज़रूरत नहीं है।

फ़ाइल नाम समस्या विकल्प के xargsबिना एक समस्या है -0, और 'शून्य फ़ाइल नाम के साथ भी चलाएँ' समस्या -0विकल्प के साथ या उसके बिना समस्या है - लेकिन GNU के xargsपास -rया --no-run-if-emptyऐसा होने से रोकने का विकल्प है। इसके अलावा, यह अंकन प्रक्रियाओं की संख्या में कटौती करता है, न कि यह कि आप प्रदर्शन के अंतर को माप सकते हैं। इसलिए, आप समझदारी से लिख सकते हैं:

find . -exec grep something {} +

क्लासिक संस्करण

find . -print | xargs grep something

आप लिनक्स पर हैं या जीएनयू है findऔर xargsआदेश, तो का उपयोग -print0के साथ findऔर -0साथ xargsसंभाल फ़ाइल रिक्त स्थान और अन्य सभी छोटे गेंद वर्ण युक्त नाम के लिए।

find . -print0 | xargs -0 grep something

से परिणामों को छोटा करना grep

यदि आप फ़ाइल नाम (केवल पाठ) नहीं चाहते हैं, तो एक उपयुक्त विकल्प जोड़ें grep(आमतौर -hपर 'शीर्षकों' को दबाने के लिए)। बिल्कुल गारंटी करने के लिए फ़ाइल नाम से छपा है grep(भले ही केवल एक फ़ाइल पाया जाता है, या के अंतिम मंगलाचरण grepकेवल 1 फ़ाइल नाम दिया जाता है), तो जोड़ने /dev/nullके लिए xargsकमांड लाइन है, ताकि वहाँ हमेशा कम से कम दो फ़ाइल नाम हो जाएगा।


मेरे जैसे भ्रमित लोगों के लिए, ध्यान दें कि यह तरीका पहले खोज के सभी आउटपुट देगा, और फिर आउटपुट देगा xargs grep something
एरिक हू

3
@ एरिकहु: मैं देख सकता हूं कि आप भ्रमित हैं, लेकिन यह वह नहीं करता है जो आप कहते हैं कि यह करता है, कम से कम किसी भी यूनिक्स-आधारित प्रणाली पर नहीं जिसे मैं जानता हूं। का आउटपुट findमानक इनपुट के लिए पाइप किया गया है xargsxargsकार्यक्रम अपने मानक इनपुट पढ़ता है, सफेद स्थान पर इनपुट बंटवारे (कारतूस, नई-पंक्तियों, टैब, आदि) और आदेश के लिए शब्दों की एक संख्या जोड़ देती है grep somethingऔर कमांड लाइन निष्पादित करता है। xargsतब तक इनपुट पढ़ना और कमांड निष्पादित करना जारी रखता है जब तक कि यह इनपुट से बाहर न चला जाए। यह दिए गए इनपुट के लिए जितनी बार आवश्यक हो कमांड xargsचलाता grepहै ( findइस उदाहरण से)।
जोनाथन लेफ़लर

मेरी गलती है, यह मिलान किए गए प्रत्येक फ़ाइल के भीतर खोज करने के लिए grep का उपयोग कर रहा है। मैं बस grep के साथ खोज के उत्पादन को फ़िल्टर करने के लिए देख रहा था
एरिक हू

1
त्रुटियां सभी सुव्यवस्थित आदेशों पर मानक त्रुटि (फाइल डिस्क्रिप्टर 2) पर जाती हैं। /dev/nullत्रुटि संदेशों को खोने के लिए stderr को पुनर्निर्देशित करना ।
जोनाथन लेफ़लर

1
यह भी लाभ है कि यह फ़ाइल पथ में रिक्त स्थान के साथ बेहतर काम करता है। यहां तक ​​कि "sed'ing" "->" \ "इसे` के साथ तोड़ता है, लेकिन xargs के साथ यह पूरी तरह से काम करता है
JZL003

36

findकमांड द्वारा कमांड में लौटाए गए फाइलों की सूची को पास करने के कुछ तरीके हैं cat, हालांकि तकनीकी रूप से सभी पाइपिंग का उपयोग नहीं करते हैं, और वास्तव में कोई भी सीधे पाइप नहीं करता है cat

  1. सबसे सरल है बैकटिक्स का उपयोग करना ( `):

    cat `find [whatever]`
    

    इसका आउटपुट लेता है findऔर इसे प्रभावी रूप से कमांड लाइन पर रखता है cat। यदि findबहुत अधिक आउटपुट (कमांड-लाइन पर फिट हो सकता है) या यदि आउटपुट में विशेष वर्ण (जैसे रिक्त स्थान) हैं तो यह अच्छी तरह से काम नहीं करता है ।

  2. सहित कुछ गोले में bash, एक का उपयोग कर सकते हैं $()backticks के बजाय:

    cat $(find [whatever])
    

    यह कम पोर्टेबल है, लेकिन नेस्टेबल है। उस के अलावा, यह बहुत ज्यादा backticks के रूप में एक ही चेतावनी है।

  3. क्योंकि जो पाया गया था उस पर अन्य कमांड चलाना एक सामान्य उपयोग है find, खोजने के लिए एक -execएक्शन है जो प्रत्येक फ़ाइल के लिए एक कमांड निष्पादित करता है जो यह पाता है:

    find [whatever] -exec cat {} \;
    

    {}फ़ाइल नाम के लिए प्लेसहोल्डर है, और \;निशान आदेश के अंत में (यह संभव है के बाद अन्य कार्यों के लिए -exec।)

    यह catहर एक फ़ाइल के लिए एक बार चलने के बजाय एक बार catइसे कई फाइलनामों को पारित करने के लिए चलाएगा जो अक्षम हो सकता है और आपके पास कुछ आज्ञाओं के लिए इच्छित व्यवहार नहीं हो सकता है (हालांकि यह इसके लिए ठीक है cat)। सिंटैक्स भी टाइप करने के लिए एक अजीब है - आपको अर्धविराम से बचने की आवश्यकता है क्योंकि अर्धविराम शेल के लिए विशेष है!

  4. के कुछ संस्करणों find(सबसे विशेष रूप जीएनयू संस्करण) आप की जगह जाने ;के साथ +उपयोग करने के लिए -exec'के कम उदाहरणों को चलाने के लिए रों संलग्न मोड cat:

    find [whatever] -exec cat {} +
    

    यह प्रत्येक इनवोकेशन के लिए कई फाइलनाम पास करेगा cat, जो अधिक कुशल हो सकता है।

    ध्यान दें कि यह एकल आह्वान का उपयोग करने की गारंटी नहीं है , हालांकि। यदि कमांड लाइन बहुत लंबी होगी, तो तर्कों को कई आक्रमणों में फैलाया जाएगा cat। इसके लिए catशायद कोई बड़ी बात नहीं है, लेकिन कुछ अन्य आदेशों के लिए यह अवांछनीय तरीकों से व्यवहार को बदल सकता है। लिनक्स सिस्टम पर, कमांड लाइन की लंबाई सीमा काफी बड़ी है, इसलिए कुछ अन्य ओएस की तुलना में कई इनवोकेशन में विभाजन काफी दुर्लभ है।

  5. क्लासिक / पोर्टेबल दृष्टिकोण का उपयोग करना है xargs:

    find [whatever] | xargs cat
    

    xargsनिर्दिष्ट कमांड चलाता है ( catइस मामले में), और स्टड से जो भी पढ़ता है, उसके आधार पर तर्क जोड़ता है। वैसे ही जैसे -execके साथ +, यह ऊपर कमांड लाइन यदि आवश्यक हो तो टूट जाएगा। यही है, अगर findबहुत अधिक उत्पादन होता है, तो यह catकई बार चलेगा । जैसा कि -execपहले के बारे में अनुभाग में बताया गया है, कुछ कमांड हैं जहां इस विभाजन के परिणामस्वरूप अलग व्यवहार हो सकता है। ध्यान दें कि xargsइस तरह के उपयोग से फ़ाइल नाम में रिक्त स्थान के साथ समस्याएँ होती हैं, जैसे xargsकि व्हिम्सस्पेस को एक सीमांकक के रूप में उपयोग किया जाता है।

  6. सबसे मजबूत, पोर्टेबल और कुशल विधि भी उपयोग करती है xargs:

    find [whatever] -print0 | xargs -0 cat
    

    -print0ध्वज बताता है findउपयोग करने के लिए \0(शून्य चरित्र) सीमांकक फ़ाइल नामों के बीच, और -0ध्वज बताता है xargsइन की उम्मीद \0सीमांकक। यह बहुत अधिक समान व्यवहार है -exec... +दृष्टिकोण, हालांकि अधिक पोर्टेबल है (लेकिन दुर्भाग्य से अधिक क्रिया)।


बैकटिक विधि महान है, क्योंकि यह अन्य आदेशों के लिए भी काम करती है ls, जैसे कि ।
मार्टिन ब्रौन

@Martin ब्रौन के $()अलावा अन्य कमांड के साथ भी काम करता है find
लॉरेंस गोंसाल्वेस

धन्यवाद, पता करने के लिए अच्छा है, मैं थोड़े (1) के बाद पढ़ना बंद कर देता हूं, क्योंकि यह मेरी जरूरतों को पूरा करता है, क्योंकि मैं विशेष पात्रों जैसे रिक्त स्थान और इस तरह से काम नहीं कर रहा हूं।
मार्टिन ब्रौन

9

इसे प्राप्त करने के लिए (बाश का उपयोग करके) मैं इस प्रकार करूंगा:

cat $(find . -name '*.foo')

इसे "कमांड प्रतिस्थापन" के रूप में जाना जाता है और यह डिफ़ॉल्ट रूप से स्ट्रिप्स लाइन फीड करता है जो वास्तव में आश्वस्त है!

यहाँ और अधिक infos


6

मेरे लिए एक शेल स्क्रिप्ट की नौकरी की तरह लगता है:

for file in 'find -name *.xml'
do
   grep 'hello' file
done

या कुछ इस तरह का


2
यह एक मान्य है, हालांकि जरूरी नहीं कि इष्टतम, प्रश्न का उत्तर हो।
जोनाथन लेफ्लर

1
... हाँ, लेकिन यह बहुत अच्छा है यदि आप फ़ाइलनाम के साथ एक बड़ी फ़ाइल चाहते हैं।
ʍǝɥʇɐɯ

1
मुझे यह सबसे अच्छा लगता है। इस तरह एक लूप ब्लॉक अन्य चीजों को करने के लिए कमरे को छोड़ देता है।
काक्यो

4

यहाँ फाइल के नाम खोजने का मेरा तरीका है जिसमें कुछ ऐसी सामग्री है जिसकी मुझे दिलचस्पी है, बस एक ही bash लाइन जो कि फिल्म्स में रिक्त स्थान को संभालती है:

find . -name \*.xml | while read i; do grep '<?xml' "$i" >/dev/null; [ $? == 0 ] && echo $i; done

3

मैं कुछ इस तरह का उपयोग करें:

find . -name <filename> -print0 | xargs -0 cat | grep <word2search4>

" -print0लगता है" और "के लिए" तर्क " -0" "xargs" के लिए तर्क संभाल खाली स्थान के लिए फ़ाइल पथ / नामों में सही ढंग से की जरूरत है।


2

खोज कमांड में एक -exec तर्क है जिसे आप इस तरह की चीजों के लिए उपयोग कर सकते हैं, आप बस सीधे grep का उपयोग कर सकते हैं।

उदाहरण के लिए ( यहाँ से, इस पृष्ठ पर अन्य अच्छे उदाहरण ):

find . -exec grep "www.athabasca" '{}' \; -print 

2

यहाँ सामान्य उपयोग के लिए मेरा शॉट है:

grep YOURSTRING `find .`

यह फाइल का नाम प्रिंट करेगा


2

बैश में, निम्नलिखित उपयुक्त होगा:

find /dir -type f -print0 | xargs -0i cat {} | grep whatever

यह /dirडायरेक्टरी की सभी फाइलों को ढूंढ लेगा और सुरक्षित रूप से फाइलनाम को पाइप xargsकरेगा, जो सुरक्षित रूप से ड्राइव करेगा grep

xargsयदि आपके पास कई हजारों फाइलें हैं /dir, तो लंघन एक अच्छा विचार नहीं है ; catअत्यधिक तर्क सूची की लंबाई के कारण टूट जाएगा। xargsआपके लिए यह सब छांटेगा।

-print0करने के लिए तर्क findके साथ meshes -0तर्क को xargsरिक्तियों के साथ फ़ाइल नाम ठीक से संभाल। -iकरने के लिए तर्क xargsआप फ़ाइल नाम जहां में आवश्यक डालने के लिए अनुमति देता है catकमांड लाइन। कोष्ठक से प्रतिस्थापित नाम फ़ाइलनाम द्वारा प्रतिस्थापित किया जाता catहै find



0

Ggrep का उपयोग करें ।

ggrep -H -R -I "mysearchstring" *

वर्तमान निर्देशिका या उपनिर्देशिका में स्थित पाठ वाले यूनिक्स में एक फ़ाइल की खोज करने के लिए


0

यह केवल पुनरावर्ती फ़ाइलों का नाम और सामग्री मुद्रित करेगा।

find . -type f -printf '\n\n%p:\n' -exec cat {} \;

संपादित करें (बेहतर संस्करण): यह नाम और पाठ की सामग्री (ascii) को केवल पुनरावर्ती रूप से मुद्रित करेगा।

find . -type f -exec grep -Iq . {} \; -print | xargs awk 'FNR==1{print FILENAME ":" $0; }'

एक और कोशिश

find . -type f -exec grep -Iq . {} \; -printf "\n%p:" -exec cat {} \;

-1

क्या आप फ़ाइलों में पाठ खोजने का प्रयास कर रहे हैं? आप बस उस के लिए grep का उपयोग कर सकते हैं ...

grep searchterm *

-1

निर्देशिका और ghi और / jkl में एक सर्वर पर सभी abc.def फ़ाइलों की सामग्री को सूचीबद्ध करने और देखने के लिए

find /ghi /jkl -type f -name abc.def 2> /dev/null -exec ls {} \; -exec cat {} \;

Abc.def फ़ाइलों को सूचीबद्ध करने के लिए, जिन्होंने प्रविष्टियों पर टिप्पणी की है और उन प्रविष्टियों को निर्देशिका / ghi और / jkl में देखते हैं

find /ghi /jkl -type f -name abc.def 2> /dev/null -exec grep -H ^# {} \;
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.