सभी निर्देशिकाओं में सीडी, उस निर्देशिका में फ़ाइलों पर कमांड निष्पादित करें, और पिछले वर्तमान निर्देशिका पर वापस लौटें


41

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


1
दी गई जानकारी के वर्तमान स्तर को देखते हुए, मुझे इसकी कोई प्रासंगिकता नहीं दिखती youtube-dl
हेलूजहोस्ट

जवाबों:


83
for d in ./*/ ; do (cd "$d" && somecommand); done

12
इसलिए जब से उत्तरदाता ने किसी भी प्रकार की व्याख्या छोड़ दी है, मैं एक प्रयास करूँगा। for d in ./*/एक लूप शुरू होता है जो ./*/एक चर में (इस मामले में, फ़ाइलों / फ़ोल्डरों की सूची) में प्रत्येक आइटम को संग्रहीत करता है $ddo (cd "$d" && somecommand);लूप के शरीर को शुरू करता है। शरीर के अंदर, यह एक उपधारा शुरू करता है और चलाता है cdऔर somecommandआदेश देता है। चूंकि यह एक चाइल्ड शेल है, पैरेंट शेल (वह शेल जिससे आप यह कमांड चला रहे हैं) अपने CWD और अन्य पर्यावरण चर को बनाए रखता है। doneबस लूप बॉडी को बंद कर देता है।
Qix

निर्देशिका के उप-निर्देशिकाओं के लिए यह तरीका:, for d in ./*/ ; do (cd "$d" && ls); doneकाम नहीं करेगा। लेकिन, for d in ./*/ ; do (cd "$d" && for d in ./*/ ; do (cd "$d" && ls); done ); doneकाम करेगा। इस उदाहरण में कमांड के रूप में -use ls।
माइकल दिमित्

-bash: cd: ./*/: No such file or directory
एस। तारिक inetin

15

सबसे अच्छा तरीका है कि इसका उपयोग न करें cd:

find some/dir -type f -execdir somecommand {} \;

execdirकी तरह है exec, लेकिन काम करने की निर्देशिका अलग है:

   -execdir command {} [;|+]
          Like   -exec,   but  the  specified  command  is  run  from  the
          subdirectory containing the matched file, which is not  normally
          the  directory  in  which  you  started  find.  This a much more
          secure  method  for  invoking  commands,  as  it   avoids   race
          conditions  during resolution of the paths to the matched files.

यह POSIX नहीं है।


क्या यह उपनाम के साथ काम करता है? मेरे पास कुछ फ़ाइलों को डाउनलोड करने के लिए एक है, लेकिन जब मैं इसे खोजता हूं तो यह इसे पहचान नहीं रहा है।
कुछ जोन्स 15

@SomethingJones नहीं, findउन आदेशों को निष्पादित करता है, इसलिए यह उपनाम के बारे में पता नहीं होगा। एक निर्देशिका क्या है mdऔर क्या है .link?
मूरू

.link एक टेक्स्ट फ़ाइल है जिसमें URL है जिसे उसे डाउनलोड करना होगा। md झंडे के झुंड के साथ सेट करने के लिए एक उपनाम है। वहाँ यह उपनाम के बारे में पता करने के लिए एक रास्ता है?
कुछ जोन्स

अपने विशेष यूज-केस के लिए @SomethingJones, में bash: find . -type f -iname '*.link' -execdir ${BASH_ALIASES[md]} -i {} \;आप सब करने की ज़रूरत नहीं है catके साथ wgetजो एक है, -iएक फ़ाइल से एक यूआरएल में पढ़ने के लिए झंडा। इसके अलावा यह आपके मूल प्रश्न से कुछ अलग है (क्योंकि आप केवल फाइलों में रुचि रखते हैं, .linkन कि किसी अन्य फाइल में जो वर्तमान में हो सकती है)।
मुरु

क्या आप जानते हैं कि कैसे करना है? मैंने कोशिश की कि आपने मुझे क्या दिया और मुझे "खराब प्रतिस्थापन" त्रुटि मिल रही है। इसके अलावा, मैं .link फ़ाइल की सामग्री कैसे निकाल पाऊंगा? मुझे पता है कि मुझे इस मामले में इसकी आवश्यकता नहीं है लेकिन मुझे लगता है कि मैं जल्द ही ऐसा करूंगा।
कुछ जोन्स 21

2
cd -P .
for dir in ./*/
do cd -P "$dir" ||continue
   printf %s\\n "$PWD" >&2
   command && cd "$OLDPWD" || 
! break; done || ! cd - >&2

उपर्युक्त आदेश को किसी भी उपधारा को करने की आवश्यकता नहीं है - यह वैकल्पिक रूप से वर्तमान शेल में अपनी प्रगति को ट्रैक करता है $OLDPWDऔर $PWD। जब आप cd -शेल इन दो चर के मूल्य का आदान-प्रदान करते हैं, तो मूल रूप से, यह निर्देशिकाओं को बदलता है। यह प्रत्येक डायरेक्टरी के लिए नाम भी प्रिंट करता है क्योंकि यह वहां काम करता है।

मुझे बस इस पर दूसरा नज़र रखना था और मैंने फैसला किया कि मैं त्रुटि से निपटने के लिए बेहतर काम कर सकता हूं। यह एक dir को छोड़ेगा जिसमें यह नहीं हो सकता है cd- और cdयह संदेश देगा कि क्यों stderr करने के लिए एक संदेश मुद्रित करेगा - और यह breakw / एक गैर-शून्य निकास कोड होगा यदि आपका commandसफलतापूर्वक निष्पादित नहीं होता है या यदि commandकिसी तरह चल रहा है तो यह आपकी मूल निर्देशिका पर लौटने की क्षमता को प्रभावित करता है। - $OLDPWD। उस मामले में यह एक cd -अंतिम भी करता है - और परिणामी वर्तमान कार्यशील निर्देशिका नाम को stderr पर लिखता है।


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