linux मैं लिनक्स पर विशिष्ट पाठ वाली सभी फाइलें कैसे ढूंढूं?




text grep (24)

सभी पिछले उत्तरों grep और खोजने का सुझाव देते हैं। लेकिन एक और तरीका है: मध्यरात्रि कमांडर का प्रयोग करें

यह एक मुफ्त उपयोगिता है (30 साल पुराना, समय के साथ साबित) जो जीयूआई के बिना दृश्य है। बहुत सारे काम हैं, फाइल ढूंढना उनमें से एक है।

मैं टेक्स्ट की एक विशिष्ट स्ट्रिंग वाली सभी फाइलों के लिए अपने पूरे लिनक्स सिस्टम को स्कैन करने का एक तरीका खोजने का प्रयास कर रहा हूं। बस स्पष्ट करने के लिए, मैं फ़ाइल के भीतर फ़ाइल की तलाश में हूं, फ़ाइल नाम में नहीं।

जब मैं देख रहा था कि यह कैसे करना है, तो मैं इस समाधान में दो बार आया:

find / -type f -exec grep -H 'text-to-find-here' {} \;

हालांकि, यह काम नहीं करता है। ऐसा लगता है कि सिस्टम में हर एक फाइल प्रदर्शित होती है।

क्या यह करने के लिए उचित तरीके से यह है? यदि नहीं, तो मुझे कैसे चाहिए? फाइलों में पाठ तारों को खोजने की यह क्षमता कुछ प्रोग्रामिंग परियोजनाओं के लिए असाधारण रूप से उपयोगी होगी जो मैं कर रहा हूं।


एक ऐसा ackउपकरण है जो आप जो भी खोज रहे हैं वह ठीक करेगा।

http://linux.die.net/man/1/ack

ack -i search_string folder_path/*

आप -iकेस संवेदनशील खोज के लिए अनदेखा कर सकते हैं


परेशानी से बचें और एके-जीईपी स्थापित करें। यह बहुत सारी अनुमति और उद्धरण मुद्दों को समाप्त करता है।

apt-get install ack-grep

फिर उस निर्देशिका पर जाएं जिसे आप खोजना चाहते हैं और नीचे दिए गए आदेश को चलाएं

cd /
ack-grep "find my keyword"

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

grep -inr "Text" folder/to/be/searched/

grep -insr "pattern" *
  • i : दोनों पैटर्न और इनपुट फ़ाइलों में केस भेद को अनदेखा करें।
  • n : आउटपुट की प्रत्येक पंक्ति को अपनी इनपुट फ़ाइल के भीतर 1-आधारित लाइन नंबर के साथ उपसर्ग करें।
  • s : nonexistent या अपठनीय फ़ाइलों के बारे में त्रुटि संदेश दबाएं।
  • r : प्रत्येक निर्देशिका के तहत सभी फ़ाइलों को दोबारा पढ़ें।

निम्न कार्य करें:

grep -rnw '/path/to/somewhere/' -e 'pattern'
  • -r या -R रिकर्सिव है,
  • -n लाइन संख्या है, और
  • -w पूरे शब्द से मेल खाता है।
  • -l (लोअर-केस एल) को मिलान करने वाली फाइलों का फ़ाइल नाम देने के लिए जोड़ा जा सकता है।

इनके साथ-साथ, --include --exclude , --include , --include --exclude-dir झंडे कुशल खोज के लिए उपयोग किया जा सकता है:

  • यह केवल उन फ़ाइलों के माध्यम से खोजेगा जिनमें .c या .h एक्सटेंशन हैं:

    grep --include=\*.{c,h} -rnw '/path/to/somewhere/' -e "pattern"
    
  • यह .o एक्सटेंशन के साथ समाप्त होने वाली सभी फ़ाइलों को खोजने से बाहर कर देगा:

    grep --exclude=*.o -rnw '/path/to/somewhere/' -e "pattern"
    
  • निर्देशिकाओं के लिए --exclude-dir पैरामीटर के माध्यम से एक विशेष निर्देशिका (ies) को बाहर करना संभव है। उदाहरण के लिए, यह dirs dir1 /, dir2 / और उन सभी को मिलान करेगा * .dst /:

    grep --exclude-dir={dir1,dir2,*.dst} -rnw '/path/to/somewhere/' -e "pattern"
    

यह आपके लिए लगभग उसी उद्देश्य को प्राप्त करने के लिए, मेरे लिए बहुत अच्छा काम करता है।

अधिक विकल्पों के लिए man grep जांच करें।


दिए गए पाठ वाले फ़ाइल नामों की सूची

सबसे पहले, मुझे विश्वास है कि आपने -l बजाय -H उपयोग किया है। इसके अलावा आप {} \ बाद उद्धरण के अंदर पाठ जोड़ने का प्रयास कर सकते हैं।

find / -type f -exec grep -l "text-to-find-here" {} \; 

उदाहरण

आइए मान लें कि आप अपनी निर्देशिका के अंदर विशिष्ट टेक्स्ट "अपाचे लाइसेंस" वाली फाइलों की खोज कर रहे हैं। यह परिणाम कुछ हद तक समान प्रदर्शित करेगा (आउटपुट आपकी निर्देशिका सामग्री के आधार पर अलग होगा)।

bash-4.1$ find . -type f -exec grep -l "Apache License" {} \; 
./net/java/jvnet-parent/5/jvnet-parent-5.pom
./commons-cli/commons-cli/1.3.1/commons-cli-1.3.1.pom
./io/swagger/swagger-project/1.5.10/swagger-project-1.5.10.pom
./io/netty/netty-transport/4.1.7.Final/netty-transport-4.1.7.Final.pom
./commons-codec/commons-codec/1.9/commons-codec-1.9.pom
./commons-io/commons-io/2.4/commons-io-2.4.pom
bash-4.1$ 

केस संवेदनशीलता हटाएं

यहां तक ​​कि यदि आप "टेक्स्ट" बनाम "टेक्स्ट" जैसे मामले के बारे में उपयोग नहीं करते हैं, तो आप मामले को अनदेखा करने के लिए -i स्विच का उपयोग कर सकते हैं। आप here और विवरण पढ़ सकते हैं।

उम्मीद है कि यह आपकी मदद करता है।


grep ( GNU या BSD )

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

grep -r "class foo" .

नोट: -r - पुनरावर्ती रूप से उपनिर्देशिका खोजें।

आप विशिष्ट फ़ाइलों के भीतर खोज करने के लिए ग्लोबिंग सिंटैक्स का भी उपयोग कर सकते हैं जैसे कि:

grep "class foo" **/*.c

नोट: ग्लोबबिंग विकल्प ( ** ) का उपयोग करके, यह सभी फ़ाइलों को विशिष्ट एक्सटेंशन या पैटर्न के साथ पुनरावर्ती स्कैन करता है। इस वाक्यविन्यास को सक्षम करने के लिए, चलाएं: shopt -s globstar आप सभी फ़ाइलों के लिए **/*.* का भी उपयोग कर सकते हैं (छुपा और बिना विस्तार के) या किसी अन्य पैटर्न के लिए।

अगर आपको यह त्रुटि है कि आपका तर्क बहुत लंबा है, तो अपनी खोज को कम करने पर विचार करें, या इसके बजाय सिंटैक्स find जैसे कि:

find . -name "*.php" -execdir grep -nH --color=auto foo {} ';'

वैकल्पिक रूप से ripgrep उपयोग ripgrep

ripgrep

यदि आप बड़ी परियोजनाओं या बड़ी फ़ाइलों पर काम कर रहे हैं, तो आपको इसके बजाय ripgrep उपयोग करना चाहिए, जैसे:

rg "class foo" .

ripgrep पर दस्तावेज़, स्थापना चरण या स्रोत कोड चेकआउट करें।

यह GNU / BSD grep , ucg , ag , sift , ack , pt या इसी तरह के किसी भी अन्य उपकरण की तुलना में बहुत तेज़ है, क्योंकि यह जंग के रेगेक्स इंजन के शीर्ष पर बनाया गया है जो बहुत तेज़ खोज करने के लिए सीमित ऑटोमाटा, सिम और आक्रामक शाब्दिक अनुकूलन का उपयोग करता है ।

यह .gitignore फ़ाइलों में निर्दिष्ट पैटर्न को अनदेखा करता है, इसलिए एक ही फ़ाइल पथ को कई ग्लोब पैटर्न के साथ मिलकर मिलान किया जा सकता है।

आप सामान्य पैरामीटर का उपयोग कर सकते हैं जैसे कि:

  • -i - असंवेदनशील खोज।
  • -I - बाइनरी फाइलों को अनदेखा करें।
  • -w - पूरे शब्दों की खोज करें (आंशिक शब्द मिलान के विपरीत)।
  • -n - अपने मैच की लाइन दिखाएं।
  • -C / --context (उदाहरण के लिए -C5 ) - संदर्भ -C5 है, तो आप आसपास के कोड देखते हैं।
  • --color=auto - मिलान करने वाले पाठ को चिह्नित करें।
  • -H - फ़ाइल नाम प्रदर्शित करता है जहां पाठ मिलता है।
  • -c - मिलान लाइनों की गिनती प्रदर्शित करता है। -H के साथ जोड़ा जा सकता है।

आप ack उपयोग कर सकते हैं। यह स्रोत कोड के लिए grep की तरह है। आप इसके साथ अपनी पूरी फाइल सिस्टम स्कैन कर सकते हैं।

बस करो:

ack 'text-to-find-here'

आपकी मूल निर्देशिका में।

आप नियमित अभिव्यक्तियों का भी उपयोग कर सकते हैं, फ़ाइल प्रकार निर्दिष्ट कर सकते हैं आदि।

अद्यतन करें

मैंने अभी सिल्वर सर्चर की खोज की है , जो कि एक की तरह है लेकिन 3-5x तेज है और यहां तक ​​कि एक .gitignore फ़ाइल से पैटर्न को अनदेखा करता है।


मैं इस बात से मोहक हूं कि grep इसे 'आरएल' के साथ कैसे बनाता है

grep -rl 'pattern_to_find' /path/where/to/find

-r to find recursively file / directory inside directories..
-l to list files matching the 'pattern'

फ़ाइल नामों को देखने के लिए 'l' के बिना '-r' का प्रयोग करें जिसके बाद पैटर्न पाया जाता है !

grep -r 'pattern_to_find' /path/where/to/find

बिल्कुल सही काम करता है ..

आशा करता हूँ की ये काम करेगा!


grep यह हासिल करने के लिए आपका अच्छा दोस्त है।

grep -r <text_fo_find> <directory>

यदि आपको खोजने के लिए पाठ के मामले की परवाह नहीं है तो उपयोग करें

grep -ir <text_to_find> <directory>

मैंने एक पायथन लिपि लिखी जो कुछ ऐसा ही करता है। इस प्रकार किसी को इस स्क्रिप्ट का उपयोग करना चाहिए।

./sniff.py path pattern_to_search [file_pattern]

पहला तर्क, pathवह निर्देशिका है जिसमें हम पुनरावर्ती खोज करेंगे। दूसरा तर्क, pattern_to_searchएक नियमित अभिव्यक्ति है जिसे हम एक फाइल में खोजना चाहते हैं। हम Python re लाइब्रेरी में परिभाषित नियमित अभिव्यक्ति प्रारूप का उपयोग करते हैं । इस लिपि में, .न्यूलाइन से भी मेल खाता है।

तीसरा तर्क, file_patternवैकल्पिक है। यह एक और नियमित अभिव्यक्ति है जो एक फ़ाइल नाम पर काम करती है। केवल उन फ़ाइलों को जो इस नियमित अभिव्यक्ति से मेल खाते हैं, पर विचार किया जाएगा।

उदाहरण के लिए, यदि मैं पाइथन फ़ाइलों को शब्द के बाद pyवाले एक्सटेंशन के साथ खोजना चाहता हूं, तो मैं निम्न कार्य करता हूं,Pool(Adaptor

./sniff.py . "Pool(.*?Adaptor"  .*py
./Demos/snippets/cubeMeshSigNeur.py:146 
./Demos/snippets/testSigNeur.py:259 
./python/moose/multiscale/core/mumbl.py:206 
./Demos/snippets/multiComptSigNeur.py:268 

और voila, यह मिलान की गई फाइलों और रेखा संख्या का मार्ग उत्पन्न करता है जिस पर मैच मिला था। यदि एक से अधिक मैच पाए गए, तो प्रत्येक लाइन नंबर को फ़ाइल नाम में जोड़ा जाएगा।


द सिल्वर्सचर नामक एक नई उपयोगिता है

sudo apt install silversearcher-ag

यह गिट और अन्य वीसीएस के साथ मिलकर काम करता है। तो आपको किसी .git या किसी अन्य निर्देशिका में कुछ भी नहीं मिलेगा।

आप बस उपयोग कर सकते हैं

ag -ia "Search query"

और यह आपके लिए काम करेगा!


सिल्वर सर्चर एक शानदार उपकरण है, लेकिन ripgrep भी बेहतर हो सकता है।

यह लिनक्स, मैक और विंडोज पर काम करता है, और कुछ महीने पहले हैकर न्यूज पर लिखा गया था (इसमें एंड्रयू गैलेंट के ब्लॉग का एक लिंक है जिसमें गिटहब लिंक है):

Ripgrep - एक नई कमांड लाइन खोज उपकरण


मैं लिनक्स पर विशिष्ट पाठ वाली सभी फाइलें कैसे ढूंढूं? (...)

मैं इस समाधान में दो बार आया था:

find / -type f -exec grep -H 'text-to-find-here' {} \;

यदि आपके उदाहरण में find का उपयोग करना है, तो grep द्वारा जारी किए गए संदेशों से इनकार करने से इनकार करने के लिए आदेश के अंत में grep लिए बेहतर ऐड -s ( --no-messages ), और 2>/dev/null को grep और find :

grep -RIl "" .

फ़ाइलों को find के लिए मानक उपकरण ढूंढें - विशिष्ट पाठ की तलाश करते समय grep के साथ संयुक्त - यूनिक्स-जैसे प्लेटफार्मों पर। find कमांड अक्सर रास्ते में xargs के साथ संयुक्त होता है।

एक ही उद्देश्य के लिए तेज़ और आसान उपकरण मौजूद हैं - नीचे देखें। बेहतर प्रयास करें, बशर्ते वे आपके प्लेटफ़ॉर्म पर उपलब्ध हों , बेशक:

तेज और आसान विकल्प

ripgrep - चारों ओर सबसे तेज़ खोज उपकरण:

find / -type f -exec grep -sH 'text-to-find-here' {} \; 2>/dev/null

रजत खोजक :

rg 'text-to-find-here' / -l

ack :

ag 'text-to-find-here' / -l

नोट: आप कई आदेश संदेशों को छिपाने के लिए, इन आदेशों के साथ-साथ 2>/dev/null भी जोड़ सकते हैं।

चेतावनी : जब तक कि आप वास्तव में इससे बच नहीं सकते हैं, एक लंबी और अक्षम खोज से बचने के लिए '/' (रूट निर्देशिका) से खोज न करें! तो उपर्युक्त उदाहरणों में, आप बेहतर रूप से ' / ' को उप-निर्देशिका नाम से बदल देंगे, उदाहरण के लिए "/ home" जहां आप वास्तव में खोजना चाहते हैं ...


इसे इस्तेमाल करे:

find . | xargs grep 'word' -sl

नीचे दिए गए आदेश इस दृष्टिकोण के लिए ठीक काम करेंगे:

find ./ -name "file_pattern_name"  -exec grep -r "pattern" {} \;

उम्मीद है कि यह सहायता है ...

आउटपुट में अधिक जानकारी देने के लिए grep थोड़ा सा विस्तारित करना, उदाहरण के लिए, फ़ाइल में लाइन नंबर प्राप्त करने के लिए जहां पाठ निम्नानुसार किया जा सकता है:

find . -type f -name "*.*" -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searthtext"

और यदि आपको पता है कि फ़ाइल प्रकार क्या है, तो आप इस मामले में .pas OR .dfm फ़ाइलों को खोजने के लिए फ़ाइल प्रकार एक्सटेंशन निर्दिष्ट करके अपनी खोज को सीमित कर सकते हैं:

find . -type f \( -name "*.pas" -o -name "*.dfm" \) -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searchtext"

विकल्पों की संक्षिप्त व्याख्या:

  1. . खोज में वर्तमान निर्देशिका से निर्दिष्ट है।
  2. -name " *.* ": सभी फ़ाइलों के लिए ( *.pas " *.pas " -o -name " *.dfm "): केवल *.pas OR *.dfm फ़ाइलें, या निर्दिष्ट के साथ -o
  3. -type f निर्दिष्ट करता है कि आप फ़ाइलों की तलाश में हैं
  4. -print0 और - के दूसरी तरफ नहीं (पाइप) महत्वपूर्ण हैं, जो फ़ाइल से गुजरने वाले grep में फ़ाइल से गुज़रने के लिए फ़ाइल नाम पास करते हैं, xargs में रिक्त स्थान के साथ फ़ाइल नामों को पारित करने की अनुमति देते हैं, जिससे grep पथ और फ़ाइल नाम को एक स्ट्रिंग के रूप में इलाज करने की अनुमति देता है, और इसे तोड़ नहीं देता है प्रत्येक जगह पर ऊपर।

आप उपयोग कर सकते हैं:

grep -r "string to be searched"  /path/to/dir

r रिकर्सिव के लिए खड़ा है और इसलिए निर्दिष्ट पथ और इसकी उप-निर्देशिकाओं में भी खोज करेगा। यह आपको फ़ाइल नाम बताएगा और साथ ही फ़ाइल में पंक्ति को प्रिंट करेगा जहां स्ट्रिंग दिखाई देगी।

या आप जिस कोशिश कर रहे हैं उसके समान एक आदेश (उदाहरण:) सभी जावास्क्रिप्ट फ़ाइलों (* .js) में खोज के लिए:

find . -name '*.js' -exec grep -i 'string to search for' {} \; -print

यह उन फ़ाइलों में लाइनों को प्रिंट करेगा जहां टेक्स्ट दिखाई देता है, लेकिन यह फ़ाइल नाम मुद्रित नहीं करता है।

इस कमांड के अलावा, हम इसे भी लिख सकते हैं: grep -rn "खोज करने के लिए स्ट्रिंग" / पथ / से / निर्देशिका / या / file -r: रिकर्सिव सर्च एन: लाइन नंबर मैचों के लिए दिखाया जाएगा


grep का उपयोग तब भी किया जा सकता है जब हम स्ट्रिंग की तलाश नहीं कर रहे हों।

बस चल रहा है,

ack 'text-to-find-here' / -l

सभी पाठ फ़ाइलों के पथ को मुद्रित करेगा, यानी केवल प्रिंट करने योग्य वर्ण वाले लोग।


खोज स्ट्रिंग के साथ केवल उस पंक्ति को स्ट्रिंग और आउटपुट की खोज करने के लिए:

for i in $(find /path/of/target/directory -type f); do grep -i "the string to look for" "$i"; done

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

for i in $(find /usr/share/applications -type f); \
do grep -i "web browser" "$i"; done

खोज स्ट्रिंग युक्त फ़ाइल नाम प्रदर्शित करने के लिए:

for i in $(find /path/of/target/directory -type f); do if grep -i "the string to look for" "$i" > /dev/null; then echo "$i"; fi; done;

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

for i in $(find /usr/share/applications -type f); \
do if grep -i "web browser" "$i" > /dev/null; then echo "$i"; \
fi; done;

प्रयत्न:

find / -type f -exec grep -H 'text-to-find-here' {} \;

जो सभी फाइल सिस्टम खोजेगा, क्योंकि रूट फ़ोल्डर है।

घर फ़ोल्डर के उपयोग के लिए:

find ~/ -type f -exec grep -H 'text-to-find-here' {} \;

वर्तमान फ़ोल्डर के उपयोग के लिए:

find ./ -type f -exec grep -H 'text-to-find-here' {} \;

find /path -type f -exec grep -l "string" {} \;

टिप्पणियों से स्पष्टीकरण

ढूंढें एक ऐसा आदेश है जो आपको किसी दिए गए पथ की उप-निर्देशिकाओं में निर्देशिकाओं और लिंक जैसी फ़ाइलों और अन्य ऑब्जेक्ट्स खोजने देता है। यदि आप एक मुखौटा निर्दिष्ट नहीं करते हैं कि फाइलनामों को पूरा करना चाहिए, तो यह सभी निर्देशिका वस्तुओं को समझाता है।

-type f specifies that it should proceed only files, not directories etc.
-exec grep specifies that for every found file, it should run grep command, passing its filename as an argument to it, by replacing {} with the filename

यदि आपका grep रिकर्सिव खोज का समर्थन नहीं करता है, तो आप xargs साथ मिलकर जोड़ सकते हैं:

find / -type f | xargs grep 'text-to-find-here'

मुझे खोजने के लिए प्रारूप से याद रखना आसान find -exec

यह फ़ाइल नाम और मिलान लाइन की सामग्री, उदाहरण के लिए आउटपुट होगा

/home/rob/file:text-to-find-here

वैकल्पिक झंडे जिन्हें आप grep जोड़ना चाहते हैं:

  • -i - मामला असंवेदनशील खोज
  • -l - केवल उस फ़ाइल नाम को आउटपुट करें जहां मैच मिला था
  • -h - केवल उस लाइन को आउटपुट करता है जो मिलान करता है (फ़ाइल नाम नहीं)




find