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


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

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

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

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

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


3693
2018-06-06 08:06


मूल


याद रखें कि grep किसी की व्याख्या करेगा . दूसरों के बीच एक एकल चरित्र वाइल्डकार्ड के रूप में। मेरी सलाह है कि हमेशा fgrep या egrep का उपयोग करें। - Walter Tross
वैसे भी, आप लगभग वहाँ थे! बस प्रतिस्थापित करें -H साथ में -l (और शायद grep साथ में fgrep)। नामों के कुछ पैटर्न के साथ फ़ाइलों को बाहर करने के लिए आप उपयोग करेंगे find एक और उन्नत तरीके से। उपयोग करना सीखना फायदेमंद है find, हालांकि। केवल man find। - Walter Tross
find … -exec <cmd> + टाइप करना और तेज़ करना आसान है find … -exec <cmd> \;। यह केवल तभी काम करता है <cmd> फ़ाइल नाम तर्कों की किसी भी संख्या को स्वीकार करता है। निष्पादन समय में बचत विशेष रूप से बड़ी है <cmd> पाइथन या रूबी स्क्रिप्ट की तरह शुरू करने में धीमा है। - hagello
किसी दिए गए पथ में गैर-पुनरावर्ती रूप से खोजने के लिए आदेश 'grep --include = *। Txt -snw "पैटर्न" thepath / * है। - Stéphane Laurent
@ StéphaneLaurent मुझे लगता है कि आप इसे बहुत जटिल बना रहे हैं। सिर्फ कहे grep "pattern" path/*.txt - fedorqui


जवाब:


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

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

इनके साथ, --exclude, --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"
    
  • निर्देशिकाओं के लिए एक विशेष निर्देशिका (ies) को बाहर करना संभव है --exclude-dir पैरामीटर। उदाहरण के लिए, यह dirs dir1 /, dir2 / और उन सभी को मिलान करेगा * .dst /:

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

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

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


6681
2018-06-06 08:21



उपयोग करें - बहिष्कृत करें। जैसे "grep -rnw --exclude = *। ओ 'निर्देशिका' -e" पैटर्न " - rakib_
मुझे grep का - अंतर्निहित पैरामीटर बहुत उपयोगी लगता है। उदाहरण के लिए: grep -rnw --include = *। जावा। -e "जो भी मैं खोज रहा हूं" - Lucas A.
यह ध्यान देने योग्य है: ऐसा लगता है r विकल्प आलसी है (पहली निर्देशिका के बाद बंद होने की तुलना में गहराई से पहले ट्रैवर्स), जबकि R लालची है (पूरे पेड़ को सही ढंग से पार करेगा)। - Eliran Malka
नोट (विशेष रूप से नए लोगों के लिए): उपरोक्त आदेश में उद्धरण चिह्न महत्वपूर्ण हैं। - madD7
@ एलिरन माल्का R en r दोनों निर्देशिकाओं को सही ढंग से पार करेंगे, लेकिन R प्रतीकात्मक लिंक का पालन करेंगे। - bzeaman


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

grep -Ril "text-to-find-here" /
  • i अनदेखा मामले के लिए खड़ा है (आपके मामले में वैकल्पिक)।
  • R रिकर्सिव के लिए खड़ा है।
  • l "फ़ाइल नाम दिखाएं, न कि परिणाम स्वयं" के लिए खड़ा है।
  • / आपकी मशीन की जड़ से शुरू करने के लिए खड़ा है।

1087
2018-06-06 08:08



मेरे अनुभव के आधार पर, -i यह बहुत धीमा कर देता है, इसलिए यदि आवश्यक नहीं है तो इसका उपयोग न करें। इसे एक निश्चित डीआईआर में परीक्षण करें और फिर सामान्यीकृत करें। यह कुछ ही मिनटों के भीतर पूरा किया जाना चाहिए। मुझे लगता है कि एक नियमित अभिव्यक्ति इसे धीमा कर देगी। लेकिन मेरी टिप्पणियां suppositions पर आधारित हैं, मैं आपको इसका परीक्षण करने का सुझाव देता हूं time लाइन के सामने। - fedorqui
हाँ, /* उसके लिए खड़ा है। वैसे भी मैंने अभी इसका परीक्षण किया और देखा कि बस / काम करता है। - fedorqui
यदि आप रेगेक्स का उपयोग नहीं कर रहे हैं तो आप अधिकांश सिस्टम पर grep के स्थान पर fgrep का उपयोग कर सकते हैं। - markle976
हाँ @ markle976, वास्तव में मैन grep से: fgrep is the same as grep -F -> Interpret PATTERN as a list of fixed strings। - fedorqui
आप निर्देशिका के पथ के साथ / प्रतिस्थापित कर सकते हैं grep -Ril "text-to-find-here" ~/sites/ या उपयोग करें। वर्तमान निर्देशिका के लिए grep -Ril "text-to-find-here" . - Black


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

बस करो:

ack 'text-to-find-here'

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

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


अद्यतन करें

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


234
2018-06-06 08:26



बहुत उपयोगी, सरल और तेज़। चेतावनी: "डेबियन-व्युत्पन्न डिस्ट्रोज़ पर, एक को" एके-जीईपी "के रूप में पैक किया जाता है क्योंकि" एक "पहले से मौजूद है" (से beyondgrep.com/install)। आप उन लिनक्स पर एक कांजी कोड कनवर्टर चलाने का अंत कर सकते हैं ... - Jose_GD
एएके या एक-जीईआर में अच्छी हाइलाइट्स हैं, लेकिन जब उचित उपयोग किया जाता है तो + grep को प्रदर्शन में बेहतर होता है - Sławomir Lenart
ध्यान दें कि ripgrep यहां वर्णित किसी भी चीज़ की तुलना में तेज़ है, जिसमें सिल्वर सर्चर और सादा 'ओल grep भी शामिल है। देख यह ब्लॉग पोस्ट प्रमाण के लिए - Radon Rosborough


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

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

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

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

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

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

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


126
2018-03-14 23:29



खोज संस्करण के लिए Thanx। मेरा grep संस्करण (NAS के लिए busybox) में -r विकल्प नहीं है, मुझे वास्तव में एक और समाधान की आवश्यकता है! - j.c
'खोज' संस्करण के लिए धन्यवाद! फ़िल्टर करना सक्षम होना बहुत महत्वपूर्ण है '.js 'या'.txt ', आदि। कोई भी व्यक्ति जीआरपी के आखिरी पारिवारिक अवकाश से सभी मल्टी-गीगाबाइट वीडियो खोजने के लिए घंटों तक इंतजार नहीं करना चाहता, भले ही कमांड टाइप करना आसान हो। - mightypile


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

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

83
2017-07-31 13:44



सबसे आसान, verbose, पुनरावर्ती और मामला असंवेदनशील। थम्स अप। - Francesco Casula
यदि आप जोड़ते हैं -ए 3 भी बेहतर है - albanx
यह बहुत अच्छा है। - kodmanyagha


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

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

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 मामले को अनदेखा करने के लिए स्विच करें। आप और विवरण पढ़ सकते हैं यहाँ

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


50
2017-11-09 13:18



ओपी ने उन फाइलों के लिए कहा जिनमें उनकी सामग्री में टेक्स्ट शामिल नहीं है। - Auxiliary
यह आदेश क्या करता है: find आदेश के लिए पाये जाने वाले सभी पथ पारित करेंगे grep -l "text-to-find-here" <file found>"। आप फ़ाइल नाम पर प्रतिबंध जोड़ सकते हैं, उदा। find / -iname "*.txt" केवल उन फ़ाइलों में खोज करने के लिए जो नाम समाप्त होता है .txt - Mene
@ सहायक - पाठकों के लिए किसी भी भ्रम से बचने के लिए नमूना आउटपुट शामिल था। - lkamal
@Mene यह वास्तव में दुखद अवस्था है कि सहायक की टिप्पणी में आपके से अधिक वोट हैं ... भले ही उनकी टिप्पणी 2014 से है और आपका 2017 है कि उनकी टिप्पणी 6 है जब यह बिल्कुल 0 होनी चाहिए और आपके पास केवल एक (अब दो) है मैं कुछ विश्वास नहीं करना चाहता हूं। - Pryftan
@Mene कहा जा रहा है -iname मामला असंवेदनशील है जिसका अर्थ यह है कि यह भी। टीटीटी फाइलें, उदाहरण के लिए, साथ ही साथ टीएक्सटी और टेक्सास आदि भी मिलेंगे। - Pryftan


अगर आपका grep रिकर्सिव खोज का समर्थन नहीं करता है, आप गठबंधन कर सकते हैं find साथ में xargs:

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

मुझे प्रारूप के मुकाबले याद रखना आसान लगता है find -exec

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

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

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

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

47
2018-06-20 08:49



यह बराबर है grep 'text-to-find-here' फ़ाइल नाम के बिना अगर find कुछ भी नहीं मिला यह लटका होगा और उपयोगकर्ता इनपुट की प्रतीक्षा करेगा! जोड़ना --no-run-if-empty एक विकल्प के रूप में xargs। - hagello
खोज और xargs का यह संयोजन कार्य के रूप में कार्य नहीं करता है अगर फ़ाइल या निर्देशिका नामों में रिक्त स्थान होते हैं (वर्ण जो xargs विभाजक के रूप में व्याख्या करता है)। उपयोग find … -exec grep … +। यदि आप xargs के साथ मिलकर मिलकर उपयोग करने का आग्रह करते हैं, तो इसका उपयोग करें -print0 तथा -0। - hagello


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

34
2018-02-26 05:47



क्या आप समझा सकते हैं कि आपका उत्तर अन्य उत्तरों पर कैसे सुधार करता है, या यह उनसे पर्याप्त रूप से अलग कैसे है? - Amos M. Carpenter
याद रखने के लिए बहुत जटिल नहीं है, सभी पैटर्न को कवर करेगा (केस-सेंसिटीविटी -> ऑफ, फ़ाइल-नाम और लाइन नंबर शामिल है और रिकर्सली सर्च आदि करेगा) और अंत में "*" का उपयोग करके सभी निर्देशिकाओं को खोजेगा (किसी भी को निर्दिष्ट करने की आवश्यकता नहीं है पथ या निर्देशिका का नाम)। - enfinet
क्षमा करें, मुझे स्पष्ट होना चाहिए था: यदि आप अपने उत्तर में उस स्पष्टीकरण को शामिल कर सकते हैं तो यह बहुत अच्छा होगा। जैसा कि यह खड़ा है, खासतौर से इतने सारे समान उत्तरों के साथ, इस तरह के संक्षिप्त उत्तर से देखना मुश्किल है कि कोशिश करने का क्या फायदा है यह स्वीकृत उत्तर या उपरोक्त लोगों में से एक होगा। - Amos M. Carpenter
यह अच्छा जवाब + अच्छा स्पष्टीकरण है - khelili miliana
@ AmosM.Carpenter एक चीज जिसे मैं इस जवाब के बारे में पसंद करता हूं, दबाने वाले तर्क को इंगित कर रहा है, जो शोर को फ़िल्टर करने में मदद कर सकता है जो वास्तव में परिणाम प्राप्त करने के लिए कोई फर्क नहीं पड़ता। Grep कुछ "फाइलों" पर त्रुटियों को प्रिंट करता है, "फ़ंक्शन लागू नहीं किया गया", "अमान्य तर्क", "संसाधन अनुपलब्ध" आदि। - leetNightshade


grep (जीएनयू या बीएसडी)

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

grep -r "class foo" .

ध्यान दें: -r - उपरोक्त निर्देशिकाओं की खोज करें।

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

grep "class foo" **/*.c

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

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

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

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

ripgrep

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

rg "class foo" .

दस्तावेज़ों, स्थापना चरणों या स्रोत कोड को चेकआउट करें गिटहब परियोजना पृष्ठ

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

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


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

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

29
2018-05-09 10:11



मुझे विस्तारित ग्लोबिंग भी उपयोगी लगता है। लेकिन ध्यान रखें कि यदि वास्तव में बड़ी संख्या में फाइलें हैं, तो आप "तर्क सूची बहुत लंबी" त्रुटि प्राप्त कर सकते हैं। (सरल globbing भी इस तरह की त्रुटि के लिए प्रवण है)। - Yoory N.


प्रयत्न:

find . -name "*.txt" | xargs grep -i "text_pattern"

24
2017-12-10 05:47



यह वास्तव में उपयोग करने के लिए एक प्रमुख उदाहरण है xargs इस तरह .. इस पर विचार करें। echo "file bar.txt has bar" > bar.txt; echo "file foo bar.txt has foo bar" > "foo bar.txt"; echo "You should never see this foo" > foo; find . -name "*.txt" | xargs grep -i foo # ./foo:You should never see this foo । xargs यहां WRONG फ़ाइल से मेल खाता है और इच्छित फ़ाइल से मेल नहीं खाता है। या तो एक का उपयोग करें find .. -print0 | xargs -0 ... लेकिन यह एक पाइप या बेहतर का बेकार उपयोग है find ... -exec grep ... {} + - shalomb


उपयोग pwd किसी भी निर्देशिका से खोज करने के लिए, नीचे की ओर इशारा करते हुए

grep -rnw `pwd` -e "pattern"

अद्यतन करें आप जिस grep का उपयोग कर रहे हैं उसके संस्करण के आधार पर, आप छोड़ सकते हैं pwd। नए संस्करणों पर . यदि कोई निर्देशिका नहीं दी जाती है तो grep के लिए डिफ़ॉल्ट मामला प्रतीत होता है इस प्रकार:

grep -rnw -e "pattern" 

या

grep -rnw "pattern" 

ऊपर जैसा ही काम करेगा!


22
2018-05-28 12:47



का उपयोग करते हुए pwd बिल्कुल जरूरी नहीं है, क्योंकि यह डिफ़ॉल्ट है। grep -rnw "pattern" पर्याप्त होता। - fedorqui
और वास्तव में grep -rnwऔर इसी तरह तीन साल पहले उत्तर दिया गया था, मुझे नहीं लगता कि यह जवाब मूल्य कैसे जोड़ रहा है। - fedorqui
चयनित उत्तर डिफ़ॉल्ट पैटर्न नहीं दिखाता है, और 5 लोगों को यह उपयोगी लगता है - mahatmanich
"डिफ़ॉल्ट पैटर्न" के साथ आपका क्या मतलब है? स्वीकृत उत्तर में शामिल हैं grep -rnw '/path/to/somewhere/' -e "pattern" जो आपके पास है वह है। 2.3 एम विज़िट के बाद 5 वोट इसका मतलब नहीं है। - fedorqui
मैं सहमत हूं :-) मूल उत्तर में जो मैं याद कर रहा था वह उपयोग का मामला है कि आपको बिल्कुल पथ नहीं देना है या वर्तमान निर्देशिका को दोबारा खोजना नहीं है जो स्वीकृत उत्तर में दिखाई नहीं दे रहा है। इस प्रकार यह थोड़ा गहरा खोदने के लिए grep के बारे में एक अच्छा सीखने का अनुभव था। - mahatmanich