मैं उस फ़ाइल की डायरेक्टरी में जाने के लिए `find` का उपयोग कैसे करता हूँ


11

मैं एक फ़ाइल ढूंढना चाहता हूं और फिर उसमें निर्देशिका दर्ज कर सकता हूं। मैंने कोशिश की find /media/storage -name "Fedora" | xargs cdलेकिन निश्चित रूप से, मैं is not a directoryत्रुटि।

एक पंक्ति कमांड के साथ मैं इसकी मूल निर्देशिका कैसे दर्ज करूं?


1
और क्या होगा अगर कई स्थानों से कई फाइलें हैं?
सर्गी कोलोडियाज़नी

@Serg Im Fedora * .iso फ़ाइल को खोज रहा है और मुझे पता है कि केवल एक ही है। अगर वहाँ और अधिक होता तो एक पहले डायरकोट्री में प्रवेश करता, मुझे लगता है
हिरोवेज टी

के साथ टकराव में shopt -s globstar, आप कर सकते हैं cd /media/storage/**/Fedora, लेकिन यह पहले मैच में ग्लोब का मूल्यांकन करना बंद नहीं करता है (इसलिए यह स्टीलड्राइवर के समाधान की तुलना में धीमा है। इंटरैक्टिव उपयोग के लिए, मैं सामान्य रूप से माउस के लिए क्या करूंगा और निर्देशिका नाम को कॉपी / पेस्ट करूंगा,) (और alt + बैकस्पेस आवश्यकतानुसार पीछे आने वाले पथ घटकों को हटाने के लिए आवश्यक था), लेकिन अगर आप ऐसा करते हैं तो मुझे लगता है कि शेल फ़ंक्शन बनाने लायक हो सकता है।
पीटर कॉर्ड्स

1
BTW, xargs cdसंभवतः काम नहीं कर सकता। cdकेवल शेल बिल्ड के रूप में काम कर सकता है, क्योंकि इसे शेल के संदर्भ को संशोधित करना होगा। ऐसा कोई तरीका नहीं xargsहै जिससे बच्चा प्रक्रिया कर सके। IDK अगर ऐसा है तो आप "कोर्स" से मतलब है, या यदि जिस मार्ग में findप्रिंट होते हैं, उसमें रिक्त स्थान होते हैं, जो xargs द्वारा विभाजित होते हैं क्योंकि आपने उपयोग नहीं किया था -d \nया कुछ भी नहीं। या find -exec {} \;
पीटर कॉर्डेस

नोट: आप cdउस तरह नहीं चल सकते । cdमें बनाया गया एक बैश है, यदि cdएक अलग कमांड होता, तो यह बदल जाता (उसका अपना) डायर, और फिर छोड़ दिया (आपको शेल में वापस लौटा, जो पहले की तरह उसी स्थिति में है, डायर का कोई परिवर्तन नहीं)।
ctrl-alt-delor

जवाबों:


14

कम से कम यदि आपके पास जीएनयू है find, तो आप -printf '%h'निर्देशिका प्राप्त करने के लिए उपयोग कर सकते हैं

       %h     Leading directories of file's name (all but the last ele‐
              ment).  If the file name contains no slashes (since it is
              in  the  current  directory)  the %h specifier expands to
              ".".

तो आप शायद कर सकते हैं

cd "$(find /media/storage -name "Fedora" -printf '%h' -quit)"

-quitकरने के लिए कई तर्क रोकने चाहिए cdमामला एक से अधिक फ़ाइल से मेल खाता है।


1
-quitयह भी आवश्यक रूप से समर्थित नहीं है। NetBSD में इसे कहा जाता है -exit, देखें unix.stackexchange.com/a/62883/117599
phk

2
अगर प्रिंट नहीं है, तो क्या आप इसके बजाय -exec dirname कर सकते हैं?
गाय

@ अच्छा विचार हाँ जो लगता है कि यह भी काम करना चाहिए
स्टीलड्रवर

6

स्टीलड्राइवर के समाधान के समान लेकिन उपयोग करना -execdir(यदि आपका findसमर्थन करता है, जैसे कि GNU या फ्रीबीएसडी का find) इसके साथ संयोजन में pwd:

cd "$(find /media/storage -name "Fedora" -execdir pwd \; -quit)"

-quitकेवल एक ही परिणाम होने पर वैकल्पिक है और पूरी निर्देशिका को क्रॉल करने से कोई समस्या नहीं है। NetBSD पर यह -exitऔर OpenBSD पर यह मौजूद नहीं है।


और किस \;लिए है?
हृदयोज टी।

1
@HrvojeT जैसे -execइसके findलिए कमांड को निष्पादित करने के लिए मापदंडों के अंत के बारे में बताता है । लेकिन जब से हम pwdयहां मापदंडों के बिना कॉल करना चाहते हैं, हम \;इसके बाद अधिकार रखते हैं।
phk

क्या कोई findक्रियान्वयन है जो निष्पादक का समर्थन करता है लेकिन नहीं -printf %h? मेरी संभावना नहीं है। दुर्भाग्य से न तो किसी को POSIX की आवश्यकता नहीं है: /
पीटर कॉर्डेस

1
@PeterCordes FreeBSD find:: freebsd.org/cgi/man.cgi?find%281%29 (बस एक FreeBSD 11 स्थापना पर इसकी पुष्टि की।)
phk

@PeterCordes NetBSD ( netbsd.gw.com/cgi-bin/man-cgi?find++NetBSD-current ) और OpenBSD ( man.openbsd.org/OpenBSD-current/man1/find.1 ) के लिए समान है। हालांकि लैटर समर्थन नहीं करता -quit/ करती है -exit
phk

5

आप पा सकते हैं एक नया खोल चलाने निर्देशिका में यह पाता है।

exec find /media/storage -name "Fedora" -execdir "$SHELL" \;

, जिसके बाद वर्तमान निर्देशिका वह होगी जिसमें एक फ़ाइल है जिसमें Fedora नाम है। ;)

जाहिर है कि यह केवल कुछ जैसा दिखता है अगर आप कमांड टाइप कर रहे हैं तो आप क्या चाहते हैं।


4

के साथ zsh:

cd /media/storage/**/Fedora([1]:h)

करने के लिए cdपहले (वर्णमाला क्रम में) निर्देशिका है कि एक फ़ाइल कहा जाता है में Fedora

  • **: किसी भी स्तर की निर्देशिका (छिपी डायरियां डिफ़ॉल्ट रूप से छोड़ी जाती हैं, Dउन्हें शामिल करने के लिए ग्लोब क्वालीफायर का उपयोग करें)
  • [1]: केवल पहले
  • :h: हेड मॉडिफायर: dirname लें।

इसके विपरीत cd "$(find ...)", यह भी काम करता है अगर निर्देशिका नाम एक नई पंक्ति वर्ण में समाप्त होता है। एक और लाभ यह है कि जब कोई मेलिंग डायरेक्टरी नहीं होती है, तो आपको कोई मेल त्रुटि संदेश नहीं मिलेगा (जबकि अधिकांश गोले cd ""चुपचाप कुछ भी नहीं करेंगे)।

एक दोष यह है कि यह /media/storageलौटने से पहले पूरे को क्रॉल करेगा ।


बाश में, cdकई आर्गों के साथ केवल पहले आर्ग को देखता है, इसलिए cd $(dirname /media/storage/**/Fedora)काम करेगा (साथ shopt -s globstar) यदि पथ में कोई स्थान नहीं है। इसे ठीक से उद्धृत करने के लिए, मुझे लगता है कि एक बैश सरणी सबसे आसान है target=(/media/storage/**/Fedora); cd "${target%/*}":। लेकिन उस समय यह तेजी से होता है कि माउस का उपयोग करने के लिए / पेस्ट करने के बजाय अंतःक्रियात्मक रूप से आने के बजाय आउटपुट को पेस्ट करना चाहिए।
पीटर कॉर्डेस

2
@PeterCordes, कई dirnameकार्यान्वयन एक से अधिक तर्क स्वीकार नहीं करेंगे। ध्यान दें कि यह स्थान नहीं है , यह वर्तमान में $IFS(डिफ़ॉल्ट रूप से स्थान, टैब और नई रेखा) और वाइल्डकार्ड वर्णों में कोई भी वर्ण है। ध्यान दें कि कि क्या bashकी cdतुलना में अधिक एक तर्क को स्वीकार करेंगे कि यह कैसे (संकलित किया गया था पर निर्भर करता है CD_COMPLAINSमें config-top.h)। कोई कल्पना कर सकता है कि भविष्य के संस्करण bashभी अंततः zsh की तरह दो arg सुविधा को लागू करेंगे।
स्टीफन चेज़लस 20

धन्यवाद। मैंने सिर्फ GNU कोरूटिल्स dirname मैनपेज को देखा। Dirname संस्करण वैसे भी भयानक है; मैंने केवल इसका उल्लेख किया है कि कुछ ऐसा हो सकता है जिसमें आप काम करते हैं। मेरा सरणी-आधारित संस्करण उन समस्याओं में से किसी से भी ग्रस्त नहीं है, क्योंकि "${target%*/}"केवल पहले सरणी तत्व ( /Fedoraस्ट्रिप्ड के साथ ) तक फैलता है । मुझे लगता है कि पथनाम में किसी भी संभावित पात्रों के खिलाफ संस्करण पूरी तरह से मजबूत है।
पीटर कॉर्डेस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.