मुझे पता **/*.ext
है कि सभी उपनिर्देशिकाओं के मिलान में सभी फ़ाइलों का विस्तार होता है *.ext
, लेकिन एक समान विस्तार क्या है जिसमें वर्तमान निर्देशिका में भी ऐसी सभी फाइलें शामिल हैं ?
जवाबों:
यह बाश 4 में काम करेगा:
ls -l {,**/}*.ext
काम करने के लिए डबल-तारांकन ग्लोब के लिए, globstar
विकल्प को सेट करना होगा (डिफ़ॉल्ट: चालू):
shopt -s globstar
से man bash
:
globstar यदि सेट किया जाता है, तो फ़ाइल नाम विस्तार शंकु में पैटर्न ** का उपयोग किया जाता है पाठ एक फ़ाइल और शून्य या अधिक निर्देशिकाओं और से मेल खाएगा उपनिर्देशिका। यदि पैटर्न का पालन किया जाता है a /, केवल निर्देशिका और उपनिर्देशिका मेल खाते हैं।
अब मैं सोच रहा हूं कि ग्लोबस्टार प्रसंस्करण में एक बार बग हो सकता है, क्योंकि अब बस ls **/*.ext
मुझे सही परिणाम मिल रहा है।
भले ही, मैंने विश्लेषण पर ध्यान दिया किन्नोरब ने वीएलसी रिपॉजिटरी का उपयोग किया और उस विश्लेषण के साथ कुछ समस्याएं पाईं और मेरे उत्तर में तुरंत ऊपर:
find
कमांड के आउटपुट की तुलना अमान्य है क्योंकि निर्दिष्ट करने -type f
में अन्य फ़ाइल प्रकार (विशेष रूप से निर्देशिका) और ls
संभावित रूप से सूचीबद्ध कमांड शामिल नहीं हैं। इसके अलावा, सूचीबद्ध कमांड्स में से एक, ls -1 {,**/}*.*
- जो ऊपर दी गई खदान पर आधारित प्रतीत होगी, केवल उन नामों को आउटपुट करती है, जिनमें उन फ़ाइलों के लिए एक डॉट शामिल है जो उपनिर्देशिकाओं में हैं। ओपी के प्रश्न और मेरे उत्तर में एक बिंदु शामिल है क्योंकि जो मांगा जा रहा है वह एक विशिष्ट एक्सटेंशन वाली फाइल है।
हालांकि, सबसे महत्वपूर्ण बात यह है कि ls
ग्लोबस्टार पैटर्न के साथ कमांड का उपयोग करके एक विशेष मुद्दा है **
। कई डुप्लिकेट उत्पन्न होते हैं क्योंकि पैटर्न को बैश द्वारा पेड़ में सभी फ़ाइल नाम (और निर्देशिका नाम) की जांच की जाती है। यदि वे निर्देशिका हैं, तो विस्तार के बाद ls
कमांड उनमें से प्रत्येक और उनकी सामग्री को सूचीबद्ध करता है ।
उदाहरण:
हमारी वर्तमान निर्देशिका में उपनिर्देशिका A
और इसकी सामग्री है:
A
└── AB
└── ABC
├── ABC1
├── ABC2
└── ABCD
└── ABCD1
उस पेड़ में, **
"AA / AB A / AB / ABC A / AB / ABC / ABC1 A / AB / ABC / ABC2 A / AB / ABC / ABCD / AB / ABC / ABCD1" (7 प्रविष्टियाँ) का विस्तार होता है । यदि आप ऐसा करते हैं तो आपको echo **
सटीक आउटपुट मिलेगा और प्रत्येक प्रविष्टि को एक बार दर्शाया जाएगा। हालाँकि , यदि आप ऐसा करते हैं तो उन प्रविष्टियों में ls **
से प्रत्येक की एक सूची को आउटपुट करने जा रहा है । इसलिए अनिवार्य रूप से इसका ls A
पालन किया जाता है ls A/AB
, आदि, इसलिए A/AB
दो बार दिखाया जाता है। इसके अलावा, ls
प्रत्येक उपनिर्देशिका के आउटपुट को अलग करने जा रहा है:
...
<blank line>
directory name:
content-item
content-item
इसलिए wc -l
उन सभी रिक्त लाइनों और निर्देशिका नाम अनुभाग शीर्षकों का उपयोग करते हुए, जो गिनती को दूर तक फेंकता है।
यह एक और कारण है कि आपको पार्सls
क्यों नहीं करना चाहिए ।
इस आगे के विश्लेषण के परिणामस्वरूप, मैं किसी भी परिस्थिति में ग्लोबस्टार पैटर्न का उपयोग नहीं करने की सलाह देता हूं, इस तरह से फाइलों के एक पेड़ पर चलने के अलावा:
for entry in **
do
something "$entry"
done
अंतिम तुलना के रूप में, मैंने एक बैश स्रोत भंडार का उपयोग किया था जो मैंने काम किया था और यह किया:
shopt -s globstar dotglob
diff <(echo ** | tr ' ' '\n') <(find . | sed 's|\./||' | sort)
0a1
> .
मैं tr
रिक्त स्थान को नई-नई सूची में बदलता था जो केवल यहाँ मान्य है क्योंकि कोई भी नाम रिक्त स्थान शामिल नहीं करता है। मैं आउटपुट की प्रत्येक पंक्ति से sed
अग्रणी को निकालता ./
था find
। मैंने इसका आउटपुट सॉर्ट किया find
क्योंकि यह सामान्य रूप से अनसोल्ड है और बैश का ग्लब्स का विस्तार पहले से ही सॉर्ट है। जैसा कि आप देख सकते हैं, से केवल उत्पादन diff
वर्तमान निर्देशिका .
आउटपुट था find
। जब मैंने किया ls ** | wc -l
तो आउटपुट में लगभग दो बार कई लाइनें थीं।
globstar
डिफ़ॉल्ट रूप सेoff
**/*.ext
हालांकि पर्याप्त होना चाहिए। इसके अलावा, आपके पास छिपी हुई फाइलें नहीं होंगी जब तक कि आप नहीं shopt -s dotglob
।
globstar
: shopt -u globstar
।
**/*.ext
पर्याप्त नहीं होगा
यह wil वर्तमान निर्देशिका और इसके उपनिर्देशिकाओं की सभी फाइलों को प्रिंट करता है जो '.ext' में समाप्त होती हैं।
find . -name '*.ext' -print
आप का उपयोग कर सकते हैं: **/*.*
सभी फ़ाइलों को पुनरावर्ती रूप से शामिल करने के लिए (द्वारा सक्षम करें shopt -s globstar
)।
कृपया अन्य विविधताओं के परीक्षण के बारे में जानें और वे कैसे व्यवहार करते हैं।
नमूना VLC रिपॉजिटरी फ़ोल्डर में 3472 फ़ाइलों के साथ परीक्षण फ़ोल्डर:
(कुल 3472 प्रति के रूप में गिना की फाइलें: find . -type f | wc -l
)
ls -1 **/*.*
- रिटर्न 3338ls -1 {,**/}*.*
- रिटर्न 3341 ( डेनिस द्वारा प्रस्तावित )ls -1 {,**/}*
- 8265 लौटाता हैls -1 **/*
- छिपी हुई फाइलों को छोड़कर, रिटर्न 7817 ( डेनिस द्वारा प्रस्तावित )ls -1 **/{.[^.],}*
- रिटर्न 7869 ( डेनिस द्वारा प्रस्तावित )ls -1 {,**/}.?*
- रिटर्न 15855ls -1 {,**/}.*
- 20321 लौटाता हैइसलिए मुझे लगता है कि सभी फ़ाइलों को पुनरावर्ती रूप से सूचीबद्ध करने के लिए सबसे निकटतम विधि पहला उदाहरण है ( **/*.*
) gniourf-gniourf टिप्पणी के अनुसार (फाइलों का उचित एक्सटेंशन है, या विशिष्ट का उपयोग करें), जैसा कि दूसरा उदाहरण नीचे कुछ और विवरण देता है :
$ diff -u <(ls -1 {,**/}*.*) <(ls -1 **/*.*)
--- /dev/fd/63 2015-04-19 15:25:07.000000000 +0100
+++ /dev/fd/62 2015-04-19 15:25:07.000000000 +0100
@@ -1,6 +1,4 @@
COPYING.LIB
-COPYING.LIB
-Makefile.am
Makefile.am
@@ -45,7 +43,6 @@
compat/tdestroy.c
compat/vasprintf.c
configure.ac
-configure.ac
और दूसरा और भी डुप्लिकेट उत्पन्न करता है।
छिपी हुई फ़ाइलों को शामिल करने के लिए, का उपयोग करें: shopt -s dotglob
(द्वारा अक्षम shopt -u dotglob
)। यह अनुशंसित नहीं है, क्योंकि यह कमांड को प्रभावित कर सकता है जैसे कि mv
या rm
आप गलती से गलत फ़ाइलों को हटा सकते हैं।
**/*.*
) जानकारीपूर्ण पाया और सबसे अच्छा काम किया। स्वीकृत उत्तर ने शीर्ष निर्देशिका में आइटम के डुप्लिकेट का कारण बना। मेरा काम करने का पैटर्न था:"${path}"**/*.*
$ find . -type f
वह वर्तमान निर्देशिका की सभी फाइलों को सूचीबद्ध करेगा। आप -exec का उपयोग करके आउटपुट पर कुछ अन्य कमांड कर सकते हैं
$find . -type f -exec grep "foo" {} \;
यह स्ट्रिंग "फू" के लिए खोज से प्रत्येक फ़ाइल को grep करेगा।
find . -type f
वर्तमान निर्देशिका में रूट के साथ पुनरावर्ती रूप से लागू होता है, न केवल वर्तमान निर्देशिका के लिए।
वर्तमान निर्देशिका को शामिल करने के लिए ब्रेस विस्तार का उपयोग क्यों न करें?
./{*,**/*}.ext
ब्रेस का विस्तार ग्लोब विस्तार से पहले होता है, इसलिए आप प्रभावी रूप से बैश के पुराने संस्करणों के साथ क्या कर सकते हैं, और नए संस्करणों में ग्लोबस्टार के साथ बंदर करना कर सकते हैं।
इसके अलावा, यह ./
आपके ग्लोब पैटर्न में अग्रणी को शामिल करने के लिए बैश में अच्छा अभ्यास माना जाता है ।
**/*.ext
। क्या आप सुनिश्चित हैं कि यह आपके लिए काम करता है?