जवाबों:
GNU में find
आप इसके लिए -printf
पैरामीटर का उपयोग कर सकते हैं , जैसे:
find /dir1 -type f -printf "%f\n"
-o
निहित की तुलना में कम पूर्ववर्तीता है -a
, इसलिए आप अक्सर अपने -o
तर्कों को समूह में रखना चाहेंगे )
उदाहरण के लिए, -execdir
वर्तमान फ़ाइल को स्वचालित रूप से रखने का उपयोग करें {}
:
find . -type f -execdir echo '{}' ';'
आप $PWD
इसके बजाय उपयोग कर सकते हैं .
(कुछ प्रणालियों पर यह सामने में एक अतिरिक्त डॉट का उत्पादन नहीं करेगा)।
यदि आपको अभी भी एक अतिरिक्त डॉट मिला है, तो वैकल्पिक रूप से आप चला सकते हैं:
find . -type f -execdir basename '{}' ';'
-execdir utility [argument ...] ;
-execdir
प्राथमिक रूप से समान है-exec
अपवाद है कि उपयोगिता निर्देशिका कि से निष्पादित किया जाएगा के साथ प्राथमिक वर्तमान फ़ाइल रखती है ।
जब +
इसके बजाय उपयोग किया जाता है ;
, तो {}
उपयोगिता के प्रत्येक आह्वान के लिए जितना संभव हो उतने पथनामों के साथ प्रतिस्थापित किया जाता है। दूसरे शब्दों में, यह सभी फ़ाइलनामों को एक पंक्ति में मुद्रित करेगा।
./filename
बदले मुझे मिल रहा है filename
। आपकी आवश्यकताओं के आधार पर, यह ठीक हो सकता है या नहीं भी हो सकता है।
$PWD
बजाय के साथ प्रयास करें .
।
यदि आप GNU खोज का उपयोग कर रहे हैं
find . -type f -printf "%f\n"
या आप एक प्रोग्रामिंग भाषा का उपयोग कर सकते हैं जैसे रूबी (1.9+)
$ ruby -e 'Dir["**/*"].each{|x| puts File.basename(x)}'
यदि आप एक बैश (कम से कम 4) समाधान कल्पना करते हैं
shopt -s globstar
for file in **; do echo ${file##*/}; done
यदि आप केवल फ़ाइल नाम के विरुद्ध कुछ कार्रवाई चलाना चाहते हैं, तो उपयोग basename
करना कठिन हो सकता है।
उदाहरण के लिए यह:
find ~/clang+llvm-3.3/bin/ -type f -exec echo basename {} \;
बस बेसन गूंज जाएगा /my/found/path
। नहीं अगर हम फाइलनाम पर निष्पादित करना चाहते हैं तो हम क्या चाहते हैं।
लेकिन आप तब xargs
आउटपुट कर सकते हैं । उदाहरण के लिए किसी अन्य dir में नामों के आधार पर फ़ाइलों को मारने के लिए:
cd dirIwantToRMin;
find ~/clang+llvm-3.3/bin/ -type f -exec basename {} \; | xargs rm
find ~/clang+llvm-3.3/bin/ -type f -exec basename {} \;
मैक (BSD find
) उपयोग पर:
find /dir1 -type f -exec basename {} \;
-exec
और -execdir
धीमे हैं, xargs
राजा हैं।
$ alias f='time find /Applications -name "*.app" -type d -maxdepth 5'; \
f -exec basename {} \; | wc -l; \
f -execdir echo {} \; | wc -l; \
f -print0 | xargs -0 -n1 basename | wc -l; \
f -print0 | xargs -0 -n1 -P 8 basename | wc -l; \
f -print0 | xargs -0 basename | wc -l
139
0m01.17s real 0m00.20s user 0m00.93s system
139
0m01.16s real 0m00.20s user 0m00.92s system
139
0m01.05s real 0m00.17s user 0m00.85s system
139
0m00.93s real 0m00.17s user 0m00.85s system
139
0m00.88s real 0m00.12s user 0m00.75s system
xargs
समानता भी मदद करता है।
मजेदार रूप से पर्याप्त मैं xargs
बिना के अंतिम मामले की व्याख्या नहीं कर सकता -n1
। यह सही परिणाम देता है और यह सबसे तेज़ है¯\_(ツ)_/¯
( basename
केवल 1 पथ तर्क लेता है, लेकिन xargs
उन सभी को (वास्तव में 5000) बिना भेज देगा -n1
। लिनक्स और ओपनबीडीएस, केवल ओओएसओएस पर काम नहीं करता है ...)
एक लिनक्स सिस्टम से कुछ बड़ी संख्याएँ यह देखने के लिए कि कैसे -execdir
मदद करता है, लेकिन एक समानांतर की तुलना में अभी भी बहुत धीमा है xargs
:
$ alias f='time find /usr/ -maxdepth 5 -type d'
$ f -exec basename {} \; | wc -l; \
f -execdir echo {} \; | wc -l; \
f -print0 | xargs -0 -n1 basename | wc -l; \
f -print0 | xargs -0 -n1 -P 8 basename | wc -l
2358
3.63s real 0.10s user 0.41s system
2358
1.53s real 0.05s user 0.31s system
2358
1.30s real 0.03s user 0.21s system
2358
0.41s real 0.03s user 0.25s system
find
यह है -execdir
कि नई प्रक्रियाएं बनाते हुए सबसे तेज़ हो जाता है एक अपेक्षाकृत महंगा ऑपरेशन है।
जैसा कि दूसरों ने बताया है, आप संयोजन कर सकते हैं find
और basename
, लेकिन डिफ़ॉल्ट रूप से basename
कार्यक्रम केवल एक समय में एक पथ पर काम करेगा, इसलिए निष्पादन योग्य को प्रत्येक पथ ( find ... -exec
या तो का उपयोग करके find ... | xargs -n 1
) के लिए एक बार लॉन्च करना होगा , जो संभवतः धीमा हो सकता है।
आप का उपयोग करते हैं -a
पर विकल्प basename
है, तो यह एक एकल मंगलाचरण में एक से अधिक फ़ाइल नाम, जिसका अर्थ है कि आप तो उपयोग कर सकते हैं स्वीकार कर सकते हैं xargs
बिना -n 1
समूह के लिए पथ एक साथ की आमंत्रण के एक दूर छोटी संख्या में, basename
है, जो और अधिक कुशल होना चाहिए।
उदाहरण:
find /dir1 -type f -print0 | xargs -0 basename -a
यहां मैंने फ़ाइलों और निर्देशिकाओं के नाम के अंदर किसी भी व्हाट्सएप का सामना करने के लिए ( -print0
और -0
एक साथ इस्तेमाल किया जाना चाहिए) शामिल किया है।
यहाँ xargs basename -a
और xargs -n1 basename
संस्करणों के बीच एक समय की तुलना है । (एक समान-जैसी तुलना के लिए, यहां बताई गई टाइमिंग एक शुरुआती डमी रन के बाद की है, ताकि फाइल मेटाडाटा के पहले ही I / O कैश में कॉपी हो जाने के बाद वे दोनों हो जाएं।) मैंने आउटपुट को पाइप कर दिया है। cksum
दोनों मामलों में, बस यह प्रदर्शित करने के लिए कि आउटपुट उपयोग की गई विधि से स्वतंत्र है।
$ time sh -c 'find /usr/lib -type f -print0 | xargs -0 basename -a | cksum'
2532163462 546663
real 0m0.063s
user 0m0.058s
sys 0m0.040s
$ time sh -c 'find /usr/lib -type f -print0 | xargs -0 -n 1 basename | cksum'
2532163462 546663
real 0m14.504s
user 0m12.474s
sys 0m3.109s
जैसा कि आप देख सकते हैं, basename
हर बार लॉन्च करने से बचने के लिए यह वास्तव में काफी तेज है ।
basename
किसी भी अतिरिक्त कमांड लाइन तर्क की आवश्यकता के बिना कई फाइलनामों को स्वीकार किया जाएगा। -a
यहाँ का उपयोग लिनक्स पर है। ( basename --version
मुझसे कहता है basename (GNU coreutils) 8.28
।)