बैश: ls * बिना फोल्डर ग्रुपिंग के


12

यदि मैं टाइप करता हूं:

ls source/*

source/fonts:
fontello

source/images:
bg1.png                eng.png        fra.png   

मुझे फ़ोल्डर नामों से समूहीकृत फ़ाइलों की सूची मिलती है। मैं केवल फ़ाइल नामों की सूची कैसे प्राप्त कर सकता हूं?

ls source/*

source/fonts/fontello
source/images/bg1.png
source/images/eng.png
source/images/fra.png   

धन्यवाद


यदि यह स्क्रिप्टिंग उपयोग के लिए है, तो आप mywiki.wooledge.org/ParsingLs देखना चाहते हैं । (उस ने कहा, findगलत तरीके से भी उपयोग करने के तरीके हैं ; विशेष रूप से, यदि आप दौड़ रहे हैं for file in $(find ...), तो आपने उनमें से एक को मारा है)।
चार्ल्स डफी

जवाबों:


13

आउटपुट परिवर्तन के बिना यह संभव नहीं लगता, लेकिन यहां एक आसान वैकल्पिक तरीका है:

find source/ -type f

या (जीएनयू के लिए विशिष्ट), केवल आपके प्रश्न में गहराई से फाइलें प्राप्त करने के लिए:

find source/ -type f -mindepth 2 -maxdepth 2

(या यदि आप चाहते हैं कि निर्देशिकाएं lsआपको देती हैं, निकालें -type f)


5

यदि आप कुछ psychedlics ( ls -d) जोड़ते हैं तो आप ls से चिपक सकते हैं :

# mkdir test
# cd test
# mkdir A B C
# touch {A,B,C}/file*
# ls -d */*    
A/file  B/file  C/file

@Cthulhu ठीक है मेरा उदाहरण बहुत छोटा है, यदि आपके पास ए में फ़ोल्डर हैं, तो बी / ओ सी -ड आपको केवल वही चुनता है जो आपने चुना है। मुझे वास्तव में पसंद नहीं है और आप ls -d के साथ तर्क द्वारा गहराई को परिभाषित कर सकते हैं
ikrabbe

मैंने गहराई को सीमित करने के लिए अन्य उत्तर को संपादित करने का सुझाव दिया है।
o11c

@ o11c बहुत अच्छा है, लेकिन अभी भी findएक मोटा जानवर है।
.रबबे

3

आपको "गरीब आदमी" में दिलचस्पी हो सकती है find:

shopt -s globstar

shopt -s s शेल विकल्प का नाम ets है। globstarविकल्प में इस प्रकार परिभाषित किया गया है बैश (1) :

यदि सेट **किया जाता है , तो फ़ाइल नाम / pathname विस्तार संदर्भ में उपयोग किया जाने वाला पैटर्न एक फाइलों [sic] और शून्य या अधिक निर्देशिकाओं और उपनिर्देशिकाओं से मेल खाएगा । यदि पैटर्न के बाद ए /, केवल निर्देशिका और उपनिर्देशिका मेल खाते हैं।

इसलिए, आपके द्वारा किए जाने के बाद shopt -s globstar, निम्न में से कोई भी आदेश:

ls -d1 - source / **                  # 'd' के बाद का वर्ण अंक एक है। 
ls -d - स्रोत / ** | बिल्ली             # यानी, यह किसी भी कमांड को पाइप में लिख देगा। 
प्रिंटफ "% s \ n" स्रोत / **

उत्पादन का उत्पादन होगा:

source/
source/fonts
source/fonts/fontello
source/images
source/images/bg1.png
source/images/eng.png
source/images/fra.png

दुर्भाग्य से, इसमें निर्देशिका नाम भी शामिल हैं। यह जानने में आपको थोड़ी मदद मिल सकती है

printf "%s\n" source/**/

उत्पादन का उत्पादन होगा:

source/
source/fonts
source/images

यानी, केवल निर्देशिका नाम। आप एक फ़ाइल में कमांड के पहले सेट के आउटपुट को रीडायरेक्ट कर सकते हैं, ऊपर के आउटपुट को एक दूसरी फ़ाइल पर रीडायरेक्ट कर सकते हैं, और फिर पहले वाले से दूसरी फ़ाइल को हटाने के लिए, या कुछ इसी तरह का उपयोग कर सकते हैं comm, diffकेवल सादा छोड़कर। फ़ाइलें (गैर-निर्देशिका)। लेकिन ऐसा मत करो।

एक और दृष्टिकोण (जो वह नहीं है ज्यादा बेहतर) है

ls -d --file-type -- source/** | grep -v '/$'

--file-typeविकल्प बताता है lsएक प्रदर्शित करने के लिए / प्रत्येक निर्देशिका का नाम (और अन्य (विशेष के सिरों) फ़ाइल प्रकारों में अन्य वर्ण), इस तरह के अंत में:

source //                             # एक अतिरिक्त एक 
स्रोत / फोंट /                        # एक जोड़ा गया
स्रोत / फोंट / fontello
स्रोत / चित्र /                       # एक जोड़ा गया
स्रोत / images / bg1.png
स्रोत / images / eng.png
स्रोत / images / fra.png

और फिर उन grep -v '/$'रेखाओं को हटा देता है जो समाप्त होती हैं /; यानी, निर्देशिका के नाम। दुर्भाग्य से, --file-typeविकल्प POSIX द्वारा निर्दिष्ट नहीं है । यदि आपका संस्करण lsइसका समर्थन नहीं करता है, तो उपयोग करें -F। यह ऐसा है जैसे कि --file-type यह *निष्पादन योग्य फ़ाइलों के नामों के सिरों पर भी प्रदर्शित होता है, जो कुछ लोगों को कष्टप्रद लगता है। आप उन्हें समाप्त कर सकते हैं sed:

ls -dF -- source/** | sed -e '/\/$/d' -e 's/\*$//'

यदि आप सभी फाइलों (और केवल फाइलों) के साथ कुछ करना चाहते हैं, तो आप कर सकते हैं

f के लिए स्रोत / **
कर
    अगर [-f "$ f"]
    फिर
        समतल फ़ाइलों पर लागू होने वाली कमांड डालें।
    फाई
किया हुआ

टिप्पणियाँ:

  • जब lsएक टर्मिनल पर आउटपुट किया जाता है, और यह -l( एल ओएनजी) मोड में नहीं है, तो यह प्रति लाइन कई नाम लिखता है (जब तक कि नाम बहुत लंबा नहीं है)। आप इसे प्रति पंक्ति एक नाम निर्दिष्ट करके -1(एक), या आउटपुट को फ़ाइल या पाइप पर रीडायरेक्ट करके लिख सकते हैं ।
  • जब से आप एक ऐसी निर्देशिका को सूचीबद्ध कर रहे हैं जिसकी सामग्री आपने बनाई है, तो आपको वास्तव --में lsआदेशों की आवश्यकता नहीं है । *अज्ञात निर्देशिका में सूचीबद्ध होने पर आपको इसका उपयोग करना चाहिए , क्योंकि शुरू होने वाले फ़ाइल नाम के खिलाफ सुरक्षा -
  • से आउटपुट पार्स करने की कोशिश मत करो ls
  • globstarखोल विकल्प POSIX से परिभाषित किया जा करने के लिए नहीं दिखाई देता है। (वास्तव में, मुझे यकीन नहीं है कि पोसिक्स किसी भी शेल विकल्पों को पहचानता है ।) जबकि यह एक bashism, beware लगता है - यह बैश के सभी संस्करणों में मौजूद नहीं हो सकता है।
  • यदि fontsया imagesउपनिर्देशिकाएँ हैं, **तो उन सभी को, पुनरावर्ती, सभी तरह से नीचे सूचीबद्ध करेगा। गहराई को सीमित करने का एक (कुछ हद तक कीचड़ और अविश्वसनीय) तरीका है

    ls -d --file-type -- source/** | grep -v '\(/.*\)\{3\}'
    

    जो तीन या अधिक /वर्ण वाली रेखाओं को हटाता है ।

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