मैं निर्दिष्ट एक्सटेंशन वाले लोगों को छोड़कर किसी निर्देशिका की प्रत्येक फ़ाइल को कैसे सूचीबद्ध करूं?


28

मान लीजिए कि मेरे पास एक फ़ोल्डर है जिसमें .txt , .pdf , और अन्य फाइलें हैं। मैं "अन्य" फाइलें (यानी, एक्सटेंशन .txt या .pdf नहीं होने वाली फाइलें ) सूचीबद्ध करना चाहूंगा । क्या आपको ऐसा करने की कोई सलाह है?

मुझे पता है कि दी गई एक्सटेंशन नहीं होने वाली फ़ाइलों को कैसे सूचीबद्ध किया जाए। उदाहरण के लिए, यदि मैं .txt फ़ाइलों को छोड़कर सभी फ़ाइलों को सूचीबद्ध करना चाहता हूं , तो या तो

find -not -iname "*.txt"

या

ls | grep -v '\.txt$' | column

काम करने लगते हैं। लेकिन, मैं .txt फ़ाइलों या .pdf फ़ाइलों को छोड़कर सब कुछ कैसे सूचीबद्ध कर सकता हूं ? ऐसा लगता है कि मैं में तार्किक किसी प्रकार का "या" उपयोग करने की आवश्यकता findहै या grep


2
ध्यान रखें कि lsबनाम findबनाम ग्लोबिंग का व्यवहार छिपे हुए डॉटफाइल्स के लिए भिन्न हो सकता है।
jw013

1
एक और बात को ध्यान में रखें: findएक पुनरावर्ती की तरह, उपनिर्देशिका को पार कर जाएगा ls। उपयोग -maxdepth 1के साथ findइस तरह की और व्यवहार करने के लिए प्राप्त करने के लिए ls
jw013

तो कोई पुनरावर्ती, बस वर्तमान dir में फ़ाइलों को सूचीबद्ध करें?
डेज़ी

जवाबों:


28

मान लिया जाए कि इसका एक उपयुक्त संस्करण है ls, यह संभवतः सबसे सरल तरीका है:

ls -I "*.txt" -I "*.pdf"

यदि आप सभी उपनिर्देशिकाओं को पार करना चाहते हैं:

ls -I "*.txt" -I "*.pdf" -R

8
GNU lsविकल्प पोर्टेबल नहीं हैं।
bahamat

4
lsवास्तव में पोर्टेबल स्क्रिप्ट वैसे भी नहीं होती है, इसलिए मुझे लगता है कि ओपी केवल इंटरैक्टिव उपयोग के बारे में पूछ रहा है।
jw013

1
एलएस पोर्टेबल क्यों नहीं है? फिर मुझे क्या उपयोग करना चाहिए?
फ्रीडो

28

समर्थन खोजें -o

find . ! '(' -name '*.txt' -o -name '*.pdf' ')'

पूर्वता को सही बनाने के लिए आपको कोष्ठक की आवश्यकता होती है। पाते हैं बहुत सारा सामान; मैं इसके मैनपेज के माध्यम से पढ़ने का सुझाव देता हूं।

आप या भी कर सकते हैं grep(लेकिन वास्तव में, आपको आउटपुट को पार्स नहीं करना चाहिएls )

ls | grep -Ev '\.(txt|pdf)$' | column

1
धन्यवाद! मुझे आउटपुट को पार्स क्यों नहीं करना चाहिए ls?
एंड्रयू

6
@ पहले, क्योंकि यह नाजुक है (इसमें एक नई रेखा के साथ एक फ़ाइल नाम पर विचार करें - हाँ, यह एक मान्य फ़ाइल नाम है - खोज -प्रिंट0 / -exec / -delete / आदि। उस समस्या से बचें); दूसरा, क्योंकि आमतौर पर एक आसान तरीका है।
derobert

findमैनपेज के अलावा , मैं पूरी तरह से Unix Power Tools लेखों के बारे में सलाह देता हूं find, जैसे कि docstore.mik.ua/orelly/unix3/upt/ch09_06.htm और docstore.mik.ua/orelly/unix3/upt/ch09_12.htm
वाइल्डकार्ड

बस मनुष्यों के लिए कथन को डिकोड करने में मदद करने के लिए:find . NOT ( *.txt OR *.pdf )
बुद्धिमानी

12

साथ bashग्लोबिंग बढ़ाया (साथ पर बारी shopt -s extglob), ग्लोब !(*.txt|*.pdf)काम करना चाहिए। आप इस ग्लोब को किसी भी कमांड को सीधे पास कर सकते हैं, जो फाइल तर्कों को लेती है, जिसमें शामिल हैं लेकिन सीमित नहीं हैं ls


1
+1 लेकिन यदि आपने उपनिर्देशिकाएँ बनाई हैं तो उनकी सामग्री भी सूचीबद्ध की जाएगी; -dउस से बचने के लिए उपयोग करें:ls -d !(*.txt|*.pdf)
किंवदंती 2k

धन्यवाद, मैं कई फाइलों को स्वीकार करने के लिए वाक्यविन्यास के लिए बिल्कुल देख रहा था, यह यहां अच्छी तरह से फिट होगा stackoverflow.com/questions/216995/…
फ्रीडो

6

में zshसाथ extendedglob:

print -rl -- *~*.(txt|pdf)

या

print -rl -- ^*.(txt|pdf)

या kshglob(हाँ, यह ksh ग्लोबिंग है "बैश एक्सटेंडेड ग्लबिंग नहीं"):

print -rl -- !(*.txt|*.pdf)

हालांकि याद रखें कि वे डॉट फाइलें भी बाहर रखते हैं।

ksh93 में FIGNORE(गलत) विशेषता है:

FIGNORE='@(.|..|*.txt|*.pdf)'
printf '%s\n' *


3

जैसा कि derobert द्वारा सुझाया गया है, आपका सबसे अच्छा दांव उपयोग करना है find। हालांकि, आप वास्तव में अन्य कमांड के साथ पाइप लाइन में परिणाम का उपयोग कर सकते हैं

GNU (और कुछ BSD के) विधेय का findसमर्थन करते हैं -print0जो इसे NUL वर्ण द्वारा समाप्त किए गए फ़ाइल नाम को मुद्रित करने के लिए कहता है , जो फ़ाइल नाम के भीतर वर्ण की अनुमति नहीं है और गारंटी देता है कि कोई टकराव नहीं होगा। अन्य कमांडों को उनके इनपुट सीमांकक के रूप में एनयूएल का उपयोग करने का निर्देश दिया जा सकता है।

इनमें से सबसे महत्वपूर्ण जीएनयू है xargs, जो आपके द्वारा निर्दिष्ट कमांड चलाता है और कमांड लाइन के तर्कों के रूप में फाइलों की सूची को पास करता है। आप xargs -r0खोज के -print0उदाहरण के साथ संयोजन के रूप में चलाना चाहते हैं :

find . -type f ! \( -name \*.pdf -o -name \*.txt \) -print0 | xargs -r0 ls -ld

यह सुरक्षित रूप से सभी पीडीएफ और txt फ़ाइलों की एक लंबी निर्देशिका सूची को प्रिंट करता है, जिसमें रिक्त स्थान या नाम के वर्ण वाले अक्षर भी शामिल हैं।

आप इसे GNU के tarसाथ निम्नानुसार भी उपयोग कर सकते हैं :

tar -zcf myarchive.tar.gz --null --files-from <(
  find . -type f ! -name \*.tar.gz -print0)

यह उन सभी फ़ाइलों की एक tar.gz फ़ाइल बनाता है जिनके नाम .tar.gz में समाप्त नहीं होते हैं

rsync-0पैरामीटर के साथ नल-सीमांकित फ़ाइलों को भी स्वीकार करता है , जैसा कि कई अन्य करते हैं। लेकिन xargsगोंद आप आमतौर पर इस प्रकार के उद्देश्य के लिए उपयोग करेंगे। या तो उस या findकी -execसुविधा।


tarआदेश उदाहरण एक अच्छा एक है। अधिकांश प्रयोजनों के लिए, हालांकि, -execएक बेहतर फिट है।
वाइल्डकार्ड

1

यदि आपके पास एक उपनिर्देशिका नहीं है

ls !(*.pdf|*.txt)

काम भी करना चाहिए!

परंतु

ls -I "*.pdf" -I "*.txt"

सामान्य तरीका है।


0

पूरक के रूप में, यदि आप एक बैश-संगत शेल का उपयोग करते हैं, तो आप पैटर्न मिलान से resuts को निकालने के लिए GLOBIGNORE चर का उपयोग कर सकते हैं। आदमी से:

   GLOBIGNORE
          A colon-separated list of patterns defining the set of filenames
          to be ignored by pathname expansion.  If a filename matched by a
          pathname  expansion  pattern also matches one of the patterns in
          GLOBIGNORE, it is removed from the list of matches.

आपके विशेष मामले में:

sh$ (GLOBIGNORE='*.pdf:*.txt'; ls -d *)

कृपया ध्यान दें कि मैं उस कमांड को सब-शैल (कोष्ठक का उपयोग करके) के रूप में चलाता हूं ताकि मेरे इंटरेक्टिव शेल के GLOBIGNORE पर्यावरण चर में परिवर्तन न हो सके।

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