बैश ढूंढें: मिली फ़ाइल की निर्देशिका प्राप्त करें


12

मेरे पास बहुत सारे सबफ़ोल्डर के साथ "parent_folder" नाम का एक पेरेंट फ़ोल्डर है, इन सबफ़ोल्डर्स में "foo.mp4" नाम की एक फ़ाइल है।

मैं इन फ़ाइलों को ऐसा करके आसानी से पा सकता हूं:

mymacbook:parent_folder username$ find ./ -name "foo.mp4" -exec echo {} \;

अब माता-पिता / फ़ोल्डर के सापेक्ष प्रत्येक फ़ाइल का पथ लौटाता है

./path/to/foo.mp4

मैं फ़ाइल नाम के बिना, सिर्फ पथ कैसे लौट सकता हूं?


1
आदमी खोजने ( कार्रवाई ): -printf %h फ़ाइल का नाम (सभी लेकिन पिछले तत्व) के अग्रणी निर्देशिका। यदि फ़ाइल नाम में कोई स्लैश नहीं है (क्योंकि यह वर्तमान निर्देशिका में है)% h विनिर्देशक का विस्तार होता है "।"
कोस्टास

क्या आप इसका एक उदाहरण दिखा सकते हैं? क्या मुझे '-सेक्स' के पीछे या उससे पहले रखना चाहिए?
डबेलजे

find ./ -name "foo.mp4" -printf "%h\n"प्रत्येक पाया फ़ाइल के लिए पथ मुद्रित करेगा (एक लाइन द्वारा)। सामान्य से अधिक कोई भी उपयोग नहीं करता है -exec echo {}इसलिए -print(डिफ़ॉल्ट भी छोड़ा गया है) या printfकार्रवाई।
कोस्टास

2
@ कोस्टस, -printfकेवल जीएनयू है। ओपी का उल्लेख ओएस / एक्स (एक बीएसडी प्रणाली)।
स्टीफन चेज़लस

@ स्टीफनचैलेजस धन्यवाद। मैं OS / X (BSD) के लिए ऐसी कोई सीमा नहीं जानता था। गरीब गरीब मैक 'उपयोगकर्ताओं!
कोस्टास

जवाबों:


20

खोज के साथ GNU:

 find . -name foo.mp4 -printf '%h\n'

अन्य findएस के साथ , बशर्ते निर्देशिका नामों में नई वर्ण रेखाएँ न हों:

 find . -name foo.mp4 | sed 's|/[^/]*$||'

या:

 find . -name foo.mp4 -exec dirname {} \;

हालांकि इसका मतलब है कि dirnameप्रति फ़ाइल एक कमांड चल रहा है ।

यदि आपको उस पर कमांड चलाने की आवश्यकता है path, तो आप (मानक सिंटैक्स) कर सकते हैं:

 find . -name "featured.mp4" -exec sh -c '
   for file do
     dir=${file%/*}
     ffmpeg -i "$file" -c:v libvpx -b:v 1M -c:a libvorbis "$dir" featured.webm
   done' sh {} +

हालाँकि इस स्थिति में, आप -execdir(GND में उपलब्ध BSD एक्सटेंशन find) का उपयोग करने में सक्षम हो सकते हैं , जो chdir()फ़ाइल की निर्देशिका के लिए है:

 find . -name "featured.mp4" -execdir \
   ffmpeg -i {} -c:v libvpx -b:v 1M -c:a libvorbis . featured.webm \;

खबरदार, हालांकि यह है कि जब से जीएनयू कार्यान्वयन findका विस्तार होगा {}करने के लिए ./filenameयहाँ, बीएसडी वालों के लिए विस्तार filename। यह यहां ठीक है क्योंकि फ़ाइल नाम एक विकल्प के तर्क के रूप में पारित किया गया है और हमेशा featured.mp4वैसे भी होता है, लेकिन अन्य उपयोगों के लिए आपको इस बात का ध्यान रखना होगा कि फ़ाइल नाम के साथ शुरू हो सकता है ( -या +कमांड द्वारा एक विकल्प के रूप में समझा जा सकता है) या इसमें शामिल हैं =(और उदाहरण के लिए awk द्वारा एक चर असाइनमेंट के रूप में समझा जा सकता है), या अन्य वर्ण इस तरह की समस्या काperl -p/n कारण बनते हैं (उन सभी को नहीं जो GNU findके ./उपसर्ग द्वारा तय किए गए हैं हालांकि उस मामले में), आदि, जिसे आपको ध्यान में रखना होगा। ।


जब आप आवेदन करते हैं find ., तो dirname के रूप में आपके पास होगा। पूरे रास्ते के बजाय।
फारसगुल्फ

अब मैं इसका अनुवाद कैसे करूंगा? find ./ -name "featured.mp4" -exec ffmpeg -i "{}" -c:v libvpx -b:v 1M -c:a libvorbis [NEED DIRECTORY HERE] featured.webm \; आपके द्वारा बताए गए दूसरे सुझाव का उपयोग कर रहा हूं।
डबेलजे

@MohsenPahlevanzadeh, ओपी ने एक निरपेक्ष मार्ग के लिए नहीं कहा, लेकिन पथ के dirname के लिए।
स्टीफन चेजलस

@ StéphaneChazelas वोट डाउन के लिए क्षमा करें।
फारसगुल्फ

धन्यवाद @ स्टीफनचेज़लस। आपने मुझे एक ffmpeg कतार / बैच बनाने में मदद की
dubbelj

-1

नीचे दिए गए आदेश का उपयोग केवल निर्देशिका विवरण लाने के लिए भी किया जा सकता है।

find ./ -name "foo.mp4" | rev | cut -d"/" -f2- | rev

यह केवल एक स्ट्रिंग को ट्रिम करने के लिए तीन बाहरी उपयोगिताओं को कॉल करने के लिए थोड़ा अधिक लगता है।
Kusalananda
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.