2011-05-31 14 views
12

से फ़ाइलों की सूची मैं लिनक्स & बैश (या सिग्विन & बैश) में काम कर रहा हूं।यूनिक्स ढूंढें: stdin

मेरे पास एक विशाल - विशाल - निर्देशिका संरचना है, और मुझे घास के मैदान में कुछ सुइयों को ढूंढना है।

विशेष रूप से, मैं इन फ़ाइलों (20 या) के लिए देख रहा हूँ:

foo.c 
bar.h 
... 
quux.txt 

मुझे पता है कि वे कहीं . के तहत एक उपनिर्देशिका में कर रहे हैं।

मुझे पता है कि मैं उनमें से कोई भी find . -name foo.c -print के साथ पा सकता हूं। इस आदेश को निष्पादित करने में कुछ मिनट लगते हैं।

मैं इन फ़ाइलों के नामों को उनके पूर्ण निर्देशिका नाम से कैसे प्रिंट कर सकता हूं? मैं 20 अलग find एस निष्पादित नहीं करना चाहता - इसमें बहुत लंबा समय लगेगा।

क्या मैं find stdin से फ़ाइलों की सूची दे सकता हूं? एक फाइल से? क्या कोई अलग आदेश है जो मैं चाहता हूं?

क्या मुझे पहले के लिए एक लूप या कुछ का उपयोग करके -o के साथ कमांड लाइन इकट्ठा करना है?

उत्तर

11

यदि आपका निर्देशिका संरचना विशाल लेकिन बार-बार बदलती नहीं है, यह यह के बाद

cd /to/root/of/the/files 
find . -type f -print > ../LIST_OF_FILES.txt #and sometimes handy the next one too 
find . -type d -print > ../LIST_OF_DIRS.txt 

चलाने के लिए आप वास्तव में तेजी से (, ग्रेप साथ sed, आदि ..) कुछ भी पा सकते हैं और फ़ाइल को अद्यतन अच्छा है केवल तभी सूचीबद्ध होता है जब पेड़ बदल जाता है।

fgrep -f wanted_file_list.txt < LIST_OF_FILES.txt 

या सीधे: (यह एक सरल प्रतिस्थापन है अगर आप locate नहीं है)

तो,

grep '/foo.c$' LIST_OF_FILES.txt #list all foo.c in the tree.. 

जब फ़ाइलों की एक सूची प्राप्त करना चाहते हैं, तो आपको निम्न कोशिश कर सकते हैं खोजने के आदेश के साथ

find . type f -print | fgrep -f wanted_file_list.txt 

fgrep मतलब के लिए -f - गपशप पढ़ा फ़ाइल से एनएस, ताकि आप आसानी से एकाधिक पैटर्न के लिए इनपुट को कम कर सकें ...

1
+0

और एक बार मैं एक में फ़ाइलों की सूची को बचाने के सरणी, खोज कमांड बनाने के लिए एक लूप का उपयोग करें? परिस्थितियों में उपयोग करने के लिए सबसे अच्छी कमांड लाइन क्या है? – JXG

+0

आपको फ़ाइलों को सरणी में रखने की आवश्यकता नहीं है; बस सरणी में ढूंढें कमांड बनाएं और फिर इसे कॉल करें। –

+0

एर, आप यह कैसे करते हैं, बिल्कुल? – JXG

3

आपको find बीस बार चलाने की आवश्यकता नहीं है।

आपको फ़ाइल नाम विनिर्देशक की एक बहु के साथ एक एकल आदेश का निर्माण कर सकते हैं:

find . \(-name 'file1' -o -name 'file2' -o -name 'file3' \) -exec echo {} \; 
+0

-exec echo {} \; आवश्यक नहीं है। – akond

+0

हां, धन्यवाद, लेकिन मुझे 'ढूंढ' के गैर-जीएनयू संस्करण में उपयोग किया जाता है, इसलिए मैं स्पष्ट होना चाहता हूं। और यदि 'echo' को प्रतिस्थापित किया गया है, उदाहरण के लिए,' printf' हम आउटपुट का अधिक नियंत्रण कर सकते हैं। – pavium

+0

तो अगर ऐसी 20 फाइलें हैं तो '-o -name' 20 बार टाइप करने के अलावा कोई विकल्प नहीं है? यह stdin या फ़ाइल से पाइपिंग इनपुट का लाभ नहीं लेता है। –

2

locate(1) आदेश एक स्वीकार्य जवाब है? रात यह एक सूचकांक बनाता है, और आप बहुत जल्दी सूचकांक क्वेरी कर सकते हैं:

$ time locate id_rsa 
/home/sarnold/.ssh/id_rsa 
/home/sarnold/.ssh/id_rsa.pub 

real 0m0.779s 
user 0m0.760s 
sys 0m0.010s 

मैं 36 सेकंड में अपनी होम निर्देशिका में एक समान find कमांड को क्रियान्वित करना छोड़ दिया। :)

यदि रात काम नहीं करता है, तो आप क्वेरी चलाने से पहले updatedb(8) प्रोग्राम चला सकते हैं। /etc/updatedb.conf (updatedb.conf(5)) आपको विशिष्ट निर्देशिका या फ़ाइल सिस्टम प्रकारों को शामिल या निकालने के लिए चुनने देता है।

+0

यह सिद्धांत रूप में करता है कि मैं क्या करना चाहता हूं, और जो भी मैं चाहता हूं उसे पाने के लिए मैं अपनी वांछित निर्देशिका के लिए grep कर सकता हूं, लेकिन रात में काम नहीं करता है, और मुझे 'अपडेटेडबी 'के लिए अनुमति नहीं है। – JXG

+0

@JXG, मैनपेज के 'EXAMPLES' अनुभाग को अनदेखा न करें :) _To रूट के अलावा किसी अन्य उपयोगकर्ता के रूप में एक निजी mlocate डेटाबेस बनाएं, run_ 'updateb -l 0 -o db_file -U source_directory'। – sarnold

+0

हा हा, मेरे पास मेरे सिस्टम के मैनपेज में वह अनुभाग नहीं है। – JXG

0

यहां स्टडीन से फ़ाइलों की एक सूची को संसाधित करने का तरीका है और विस्तारित नियमित अभिव्यक्ति मिलान (n1|n2|n3) का उपयोग करने के लिए अपने (फ्रीबीएसडी) खोज कमांड को इकट्ठा करने का एक तरीका है।

जीएनयू आप विस्तारित नियमित अभिव्यक्ति मिलान सक्षम करने के लिए निम्न विकल्पों में से एक का उपयोग करना पड़ सकता है खोजने के लिए:

-regextype posix-egrep

-regextype posix-extended

echo ' 
foo\\.c 
bar\\.h 
quux\\.txt 
' | xargs bash -c ' 
IFS="|"; 
find -E "$PWD" -type f -regex "^.*/($*)$" -print 
echo find -E "$PWD" -type f -regex "^.*/($*)$" -print 
' arg0 

# note: "$*" uses the first character of the IFS variable as array item delimiter 
(
IFS='|' 
set -- 1 2 3 4 5 
echo "$*" # 1|2|3|4|5 
)