Emacs में निर्देशिका / उपनिर्देशिका में पुन: खोज / grep फ़ाइल सामग्री कैसे प्राप्त करें?


14

मैं काफी समय से Emacs का उपयोग कर रहा हूं और मैं अभी भी किसी तरह यह समझने में असफल हूं कि (प्रोजेक्ट) निर्देशिका के भीतर एक स्ट्रिंग के लिए (पुनरावर्ती) grep का सबसे अच्छा तरीका क्या है और परिणाम प्राप्त करें या तो बिंदीदार बफर के रूप में प्रस्तुत करें या कुछ और भी अधिक में उपयोगी तरीका। कृपया मुझे ज्ञान दो।


क्या आपने helm-projectile-grepकमांड का उपयोग करने की कोशिश की है (यदि आपके पास हेल्म प्रोजेक्टाइल स्थापित है) या projectile-grep?
चक्रवर्ती रघुनंदन

मुझे नहीं पता कि क्या है helmया क्या projectileहै, लेकिन अगर यह एक अनुशंसित उपकरण है, तो मैं इसे स्थापित और सीखूंगा।
बोरिस स्टिटनिक

हां, प्रोजेक्टाइल एक ऐसा पैकेज है जो कमांड के साथ प्रश्न में आपके द्वारा बताए गए तरीके को करने का एक आसान तरीका प्रदान करता है projectile-grep। इसके अलावा, मैं आपको helmपैकेज स्थापित करने की अत्यधिक सलाह देता हूं । मैं helmऔर बिना emacs चलाने की कल्पना नहीं कर सकते helm-projectile। आप helm-agपैकेज में भी दिलचस्प हो सकते हैं (जो emacs में चांदी के खोजकर्ता के लिए एक पतवार इंटरफ़ेस प्रदान करता है, जो कि शायद grep या ack की तुलना में तेज़ है)।
चक्रवर्ती रघुनंदन

2
ताकि भविष्य के Google और फ़ोरम खोजकर्ताओं के लिए यह प्रश्न अधिक उपयोगी और आसान हो, संभवतः शब्द को पुनरावर्ती रूप से शामिल करने के लिए प्रश्न के शीर्षक को संशोधित करने पर विचार करें, और गुंजाइश को सीमित करने पर विचार करें - उदाहरण के लिए, किसी निर्देशिका में संक्षिप्त रूप से संक्षिप्त विवरण फ़ाइल कैसे करें / उपनिर्देशिका । यह सिर्फ एक उदाहरण है - यह इसके बजाय कुछ और हो सकता है।
कानून व्यवस्था

1
हालांकि अब तक की गई टिप्पणियों और उत्तरों ने विभिन्न फैंसी तरीकों से ऐसा करने के लिए कई पैकेज सुझाए हैं, लेकिन मैं आपके सवाल से नहीं देखता कि साधारण को M-x grepवह क्यों नहीं करना चाहिए जो आपको चाहिए। चलो, आप एक मनमाना कमांड लाइन देते हैं, मैं कभी-कभी findवहां उपयोग करता हूं जब मुझे पुनरावृत्ति की आवश्यकता होती है।
MAP

जवाबों:


15

खैर, चूंकि मूल प्रश्न का उल्लेख नहीं है rgrep, इसलिए मैं आगे जाऊंगा और इसे यहां इंगित करूंगा। यह पहले से ही Emacs में बनाया गया सबसे सरल विकल्प है, और मैंने इसे अधिकांश चीजों के लिए पर्याप्त से अधिक पाया है।

प्रलेखन से,

Recursively grep for REGEXP in FILES in directory tree rooted at DIR.

खोज फ़ाइल नाम से मेल खाने वाले शेल पैटर्न FILES तक सीमित है।

तो, उदाहरण के लिए, सभी अजगर फ़ाइलें मेरे घर निर्देशिका के नीचे का उपयोग करता है के लिए खोज करने के लिए some_function, मैं के साथ यह कहेंगे some_function, *.py, ~/तर्क के रूप में। परिणाम एक नए बफर में प्रदर्शित होते हैं।


1
के find-grep-diredरूप में अच्छी तरह से उल्लेख करना चाहते हैं क्योंकि ओपी ने उल्लेख किया है "परिणाम या तो एक
बिंदास

@npostavs मैंने find-grep-diredखुद का उपयोग नहीं किया है, इसे उत्तर में जोड़ने के लिए स्वतंत्र महसूस करें।
15:26 पर user2699

मैंने एक बार ack और ag की पसंद के साथ प्रयोग किया था, इस धारणा पर कि मुझे rgrep से उन चीजों का उपयोग करने के लिए स्विच करना चाहिए, क्योंकि वे बेहतर होने वाले थे। अंत में मैं rgrep के साथ रहा, क्योंकि मुझे बदलने का कोई लाभ नहीं मिला! कमांड लाइन पर निश्चित रूप से एक मामला बनाया जाना है, लेकिन Emacs rgrepमें खोज को लक्षित करने का इतना अच्छा काम है कि उनके बीच कोई महत्वपूर्ण गति अंतर नहीं थे। (मैं कहना चाहता हूं कि rgrep कुछ मामलों में तेजी से तेज था , लेकिन मुझे यकीन है कि याद नहीं है।)
phils

1
ध्यान दें कि next-errorऔर previous-errorपरिणाम सेट के माध्यम से नेविगेट करने के लिए इस्तेमाल किया जा सकता है। मुझे लगता है M-g M-nऔर M-g M-pमानक बाइंडिंग का सबसे सुविधाजनक।
फिल्स

find-grep-diredमुझे क्रॉस-रेफ़रिंग लिंक के साथ एक बफर नहीं देता। rgrepयह मेरे लिए है और उस अंतिम सुझाव के बारे next-error previous-errorमें शानदार है! मेरी एकमात्र वक्रोक्ति यह है कि बफर की शुरुआत में सभी गन्दा कमांड निष्पादन आउटपुट।
रॉबर्ट

11

मैं ख़ुशी से M-x find-grep-diredसालों तक इस्तेमाल करता हूँ । यह एक परिणामी बफ़र के रूप में परिणाम देता है, जिसे आप उपयोग कर सकते हैं।


मुझे इसके साथ काम करने के लिए क्रॉस-रेफरेंस लिंकिंग प्राप्त करने में कुछ कठिनाई हुई है। यह कॉन्फ़िगरेशन काफी गंदा है ( find-ls-option) और आखिरकार आप कुछ के साथ समाप्त होते हैं जो कि काफी क्रिया है क्योंकि यह फ़ाइल नाम से पहले की तारीख के बिना काम नहीं करता है!
रोबर्ट

5

समाधान 1 (सबसे अच्छा समाधान):

परामर्श स्थापित करें ( https://github.com/abo-abo/swiper/blob/master/c परामर्श. el )

तब M-x counsel-git-grep

किसी भी सेटअप की जरूरत नहीं है (git प्रोजेक्ट रूट और फाइलों को बाहर करने के लिए जानता है)। दोनों git grepऔर counselकुशल है।

परियोजना की आवश्यकता गिट द्वारा प्रबंधित की जानी चाहिए।

वकील को आइवी-मोड की आवश्यकता होती है।

समाधान 2:

यह समाधान grep का उपयोग करता है और किसी भी परियोजना पर काम करता है। यह समाधान 1 से नीच है क्योंकि यह धीमा है और मैनुअल सेटअप की आवश्यकता है। यह आइवी-मोड पर भी आधारित है।

(defvar simple-project-root "~/.emacs.d")
(defun simple-grep ()
  (interactive)
  (unless (featurep 'ivy)
    (require 'ivy))
  (let* ((default-directory (file-name-as-directory simple-project-root))
         (keyword (read-string "Keyword:")))
    (ivy-read (format "Grep at %s:" simple-project-root)
              (split-string (shell-command-to-string (format "grep -rsnI %s ." keyword)) "\n" t)
              :action (lambda (val)
                        (let* ((lst (split-string val ":"))
                               (linenum (string-to-number (cadr lst))))
                          ;; open file
                          (find-file (car lst))
                          ;; goto line if line number exists
                          (when (and linenum (> linenum 0))
                            (goto-char (point-min))
                            (forward-line (1- linenum))))))))

आपको तकनीकी। विवरण के लिए .dir-locals.el सेट करना होगा simple-project-root, https://www.gnu.org/software/emacs/manual/html_node/emacs/Directory-Variables.html देखें

समाधान 2 में कोड सिर्फ एक प्रोटोटाइप है। मेरा वास्तविक कार्यान्वयन बहुत अधिक जटिल है। देखें counsel-etags-grepमें https://github.com/redguardtoo/counsel-etags/blob/master/counsel-etags.el

सारांश:

वे सबसे अच्छे दो उपाय हैं जो मैं जानता हूं।

यदि कोई अन्य बेहतर समाधान मौजूद है, तो उन्हें उत्पादन-तैयार होने के लिए कम से कम समस्याओं को हल करने की आवश्यकता है,

  • grep में कीवर्ड कैसे प्राप्त करें (उदाहरण के लिए, चयनित क्षेत्र से कीवर्ड प्राप्त करें)

  • कीवर्ड से बचें

  • यदि अधिक कुशल grep प्रोग्राम मौजूद है, तो हमें इसका उपयोग करना चाहिए (ripgrep, the_silver_searcher / ag, ... आदि), या फिर डिफ़ॉल्ट grep को वापस कर दें।

  • उम्मीदवार विंडो को स्क्रीन की पूरी चौड़ाई का उपयोग करना चाहिए और उपयोगकर्ता उम्मीदवारों को अंतःक्रियात्मक रूप से फ़िल्टर कर सकते हैं (इसीलिए लोग आइवी या हेल्म का उपयोग करते हैं)

  • हमें उम्मीदवार विंडो में संबंधित पथ दिखाना चाहिए

  • पिछले grepped परिणाम का फिर से उपयोग करने में सक्षम। इसलिए पिछले परिणाम को बचाया जाना चाहिए। आप ivy-resumeसे ivyया helm-resumeसे उपयोग कर सकते हैंhelm

  • जब आप पिछले grepped परिणाम सहेजते हैं, तो पिछले परिणाम का संदर्भ भी सहेजा जाना चाहिए। उदाहरण के लिए, समाधान 2 के कोड में default-directoryसंदर्भ है। अधिक जानकारी के लिए https://github.com/abo-abo/swiper/issues/591 देखें ।

  • विस्तारित नियमित अभिव्यक्ति का उपयोग किया जाना चाहिए क्योंकि यह सरल है और पहले से ही counsel-git-grepthe_silver_searcher / ag द्वारा उपयोग किया जाता है ।


4

मैं @chen बिन के समाधान में एक और समाधान जोड़ना चाहूंगा जो भी उपयोग करता है counsel(लेकिन आपको इसके लिए किसी परियोजना को बनाए रखने की आवश्यकता नहीं है git)।

आपको ag (सिल्वर खोजकर्ता) को स्थापित करने की आवश्यकता है और counselकमांड प्रदान करता है counsel-agजो दर्ज किए गए स्ट्रिंग के लिए वर्तमान निर्देशिका को खोजता है।

यदि आप किसी परियोजना के भीतर खोज करना चाहते हैं (न कि केवल वर्तमान कार्यशील निर्देशिका), तो इसे अपने में जोड़ें .emacs: -

  (defun rag/counsel-ag-project-at-point ()
    "use counsel ag to search for the word at point in the project"
    (interactive)
    (counsel-ag (thing-at-point 'symbol) (projectile-project-root)))

यह फ़ंक्शन agप्रोजेक्ट रूट डायरेक्टरी को पुन: खोज करने के लिए उपयोग करेगा ।

संपादित करें : खोज के लिए बिंदु पर उपर्युक्त फ़ंक्शन डिफॉल्ट करता है। यदि आपको वह व्यवहार पसंद नहीं है, तो उसके (thing-at-point 'symbol)साथ बदलें nil। और यदि आप चाहते हैं कि खोज परिणाम इसमें स्वयं बफर प्रेस होC-c C-o

EDIT2 : यदि आप किया है ripgrepस्थापित है, तो आप बदल सकते हैं counsel-agके साथ counsel-rgऊपर समारोह में और तब भी वह अच्छे के रूप में हूँ :)


है projectile-project-rootरेल परियोजना जड़ खोजने के लिए useable?
बोरिस स्टिटनिक 12

हां, जब तक यह एक वैध प्रोजेक्टाइल प्रोजेक्ट है तब तक यह काम करेगा। मेरे विचार से प्रोजेक्टाइल-रेल्स नामक कुछ पैकेज था।
चक्रवर्ती रघुनंदन

आपने फ़ंक्शन का नाम क्यों दिया rag/...?
बोरिस स्टिटनिक 15

यह एक सामान्य शैली है जिसे लोग अक्सर अपने स्वयं के कार्यों को लिखते समय उपयोग करते हैं (यदि आप इसे अपने खाली कॉन्फ़िगरेशन को ब्राउज़ करते हैं तो आप इसे बहुत अधिक लोगों द्वारा किया जा सकता है)। मेरे द्वारा परिभाषित सभी कार्य rag/उपसर्ग के साथ शुरू होते हैं और इससे उन्हें नीचे ढूंढना आसान हो जाता है M-x:)
चक्रवर्ती रघुनंदन


2

यहाँ एक कस्टम grep फ़ंक्शन का एक उदाहरण है जो एक निर्देशिका और उसके उपनिर्देशिकाओं में फ़ाइल सामग्री (खोज शब्द के लिए एक regexp का उपयोग करके) को पुन: प्राप्त करता है और परिणामों को पहले और बाद में संदर्भ की पंक्तियों के साथ प्रदर्शित करता है। अंतर्निहित compile.elऔर grep.elलाइब्रेरी खोज परिणामों वाले फ़ाइल में स्थान पर कूदने के लिए कई तरीके प्रदान करते हैं। इस उदाहरण के लिए काम करने के लिए और कुछ भी स्थापित करने की आवश्यकता नहीं है - जो सभी आवश्यक है वह Emacs का एक पूर्ण संस्करण और एक कंप्यूटर है जिसमें grepउपयोगिता स्थापित है। यदि डिफ़ॉल्ट पर्याप्त नहीं है, तो चर grep-programको grepउपयोगिता के किसी विशेष स्थान को इंगित करने के लिए समायोजित किया जा सकता है ।

(defun recursive-grep ()
"Recursively grep file contents.  `i` case insensitive; `n` print line number;
`I` ignore binary files; `E` extended regular expressions; `r` recursive"
(interactive)
  (let* ((search-term (read-string "regex:  "))
         (search-path
           (directory-file-name (expand-file-name (read-directory-name "directory:  "))))
         (default-directory (file-name-as-directory search-path))
         (grep-command
           (concat
             grep-program
             " "
             "-inIEr --color=always -C2"
             " "
             search-term
             " "
             search-path)))
    (compilation-start grep-command 'grep-mode (lambda (mode) "*grep*") nil)))

हालांकि यह सवाल नहीं उठाता है कि उपरोक्त grep फ़ंक्शन द्वारा परिणाम के रूप में लौटाए गए कई फ़ाइलों को एक साथ कैसे संशोधित किया जाए, मुझे यह उपयोग करने में बहुत उपयोगी लगता है multiple-cursorsऔर wgrep। यह एक हवा में गिर गई एक में कई फ़ाइलों को संशोधित करता है। हालांकि, पुस्तकालयों ने कहा, अगर उन सुविधाओं को वांछित किया जाता है तो उन्हें स्थापित करने की आवश्यकता होगी।
कानून व्यवस्था

बिलिन के ऊपर इसका उपयोग करने का क्या फायदा है rgrep?
npostavs

1
@npostavs - मुझे rgrepअपने पसंदीदा रेगेक्स खोज मानदंड को अनुकूलित करने के लिए अंतर्निहित समय-समय पर मिला , और मैंने कस्टम फ़ंक्शन में सब कुछ हार्ड-कोड करने के लिए चुना (जो मैं प्रत्येक दिन कई बार उपयोग करता हूं)। यदि आप एक वैकल्पिक उत्तर लिखना चाहते हैं जो बताता है कि कैसे अनुकूलित किया जाए rgrep, तो यह भविष्य में अन्य फोरम पाठकों के लिए उपयोगी होगा।
कानून व्यवस्था
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.