एक निर्देशिका में एक्सटेंशन पीडीएफ के साथ फ़ाइलों को छोड़कर सभी फ़ाइलों को हटा दें


50

मेरे पास एक निर्देशिका है जिसमें निम्नलिखित शामिल हैं:

x.pdf
y.zip
z.mp3
a.pdf

मैं x.pdfऔर से अलग सभी फ़ाइलों को हटाना चाहते हैं a.pdf। मैं टर्मिनल से यह कैसे करूँ? कोई उपनिर्देशिका नहीं हैं इसलिए किसी भी पुनरावृत्ति की आवश्यकता नहीं है।

जवाबों:


63
cd <the directory you want>
find . -type f ! -iname "*.pdf" -delete
  • पहला कमांड आपको उस निर्देशिका में ले जाएगा, जिसमें आप अपनी फ़ाइलों को हटाना चाहते हैं
  • दूसरा कमांड .pdfफ़ाइलनाम में समाप्त होने वाले को छोड़कर सभी फ़ाइलों को हटा देगा

उदाहरण के लिए, यदि tempआपके होम फोल्डर में कोई निर्देशिका है, तो :

cd ~/temp

फिर फ़ाइलें हटाएं:

find . -type f ! -iname "*.pdf" -delete

यह छोड़कर सभी फ़ाइलों को हटा देगा xyz.pdf

आप इन दोनों आदेशों को इसमें जोड़ सकते हैं:

find ~/temp -type f ! -iname "*.pdf" -delete

.वर्तमान निर्देशिका है। अंत के !साथ वाले के अलावा सभी फ़ाइलों को लेने का मतलब है .pdf-type fकेवल फाइलों का चयन करता है, निर्देशिकाओं का नहीं। -deleteइसे हटाने का मतलब है।

नोट: यह कमांड सभी फाइलों (मौजूदा फाइलों के अलावा पीडीएफ फाइलों को छोड़कर) को वर्तमान निर्देशिका में और साथ ही सभी उप-निर्देशिकाओं में हटा देगा। !पहले आना चाहिए -name। बस -nameकेवल शामिल होंगे .pdf, जबकि -inameदोनों शामिल होंगे .pdfऔर.PDF

केवल वर्तमान निर्देशिका में हटाने के लिए और उप-निर्देशिका में जोड़ने के लिए नहीं -maxdepth 1:

find . -maxdepth 1 -type f ! -iname "*.pdf" -delete

जवाब के लिए धन्यवाद। क्या आप मुझे वाक्य रचना को थोड़ा समझने में मदद कर सकते हैं? .मतलब "और"? !मतलब "को छोड़कर" -nameदर्शाता है कि आप एक नाम पैरामीटर द्वारा बाहर करना चाहते हैं और फिर -deleteखोजने पर कार्रवाई करना है? तो यह "* .pdf" को छोड़कर हर चीज की तलाश करता है और उन्हें हटा देता है? या मुझे गलत समझा है?
जेसेनोर्टन

.वर्तमान निर्देशिका का मतलब है। अंत के !साथ एक को छोड़कर सभी फ़ाइलों को लेने का मतलब है .pdf-deleteइसे हटाने का मतलब है। क्या मैं अब स्पष्ट हूँ?
एडवर्ड टोरवाल्ड्स 12

@terdon स्टार्कर्स ने कहा कि कोई उप-निर्देशिका नहीं है। बीमार मेरे जवाब को और अधिक व्यापक होने के लिए संपादित करते हैं
एडवर्ड टॉर्वाल्ड

+1 आपको -maxdepth 1शुरू करने के लिए पैरामीटर को शामिल करना चाहिए । फिर एक पुनरावर्ती को हटाना चाहता है मामले में पैरामीटर को हटाने का सुझाव दें।
ट्यूलेंस कोर्डोवा 12

3
यह मेरे ध्यान में लाया गया कि हमें -inameइसके बजाय उपयोग करना चाहिए -name, या .PDFएक एक्सटेंशन के रूप में फ़ाइलों के माध्यम से पर्ची होगी।
मुरु

43

साथ bash'विस्तारित खोल ग्लोबिंग है, आप के अलावा अन्य एक्सटेंशन के साथ किसी भी फाइल को दूर कर सकता है .pdfका उपयोग करते हुए

rm -- *.!(pdf)

जैसा कि @pts द्वारा उल्लेख किया गया है, --वर्ण किसी भी कमांड विकल्प के अंत को इंगित करते हैं, कमांड को फाइलों के दुर्लभ मामले में सुरक्षित बनाते हैं, जिनके नाम एक -चरित्र से शुरू होते हैं ।

यदि आप फ़ाइलों को बिना किसी एक्सटेंशन के और साथ ही उन एक्सटेंशनों के साथ हटाना चाहते हैं .pdf, तो जैसा कि @DennisWilliams द्वारा बताया गया है, जिसका आप उपयोग कर सकते हैं

rm -- !(*.pdf)

विस्तारित ग्लोबिंग को डिफ़ॉल्ट रूप से सक्षम किया जाना चाहिए, लेकिन यदि आप ऐसा उपयोग नहीं कर सकते हैं

shopt -s extglob

खासकर यदि आप इसे एक स्क्रिप्ट के अंदर उपयोग करने का इरादा रखते हैं, तो यह ध्यान रखना महत्वपूर्ण है कि यदि अभिव्यक्ति कुछ भी मेल नहीं खाती है (अर्थात यदि निर्देशिका में कोई गैर-पीडीएफ फाइलें नहीं हैं), तो डिफ़ॉल्ट रूप से ग्लोब को अनएक्सपेक्टेड पास किया जाएगा rmकमांड, जैसे त्रुटि

rm: cannot remove `*.!(pdf)': No such file or directory

आप nullglobशेल विकल्प का उपयोग करके इस डिफ़ॉल्ट व्यवहार को संशोधित कर सकते हैं , हालांकि इसका अपना मुद्दा है। अधिक गहन चर्चा के लिए नलग्लोब - ग्रेग का विकी देखें


बेहतर दृष्टिकोण IMO।
तक्षक

एक्सटेंशन के बिना फ़ाइलों के बारे में क्या? FWIW, zsh में यह हैrm *~*.pdf
एमिल जेकाबेक

1
मैं कोष्ठक के अंदर डॉट डालूँगा।
डेनिस विलियमसन

4
आह, तारांकन भी अंदर जाना चाहिए !(*.py):। इसके अलावा, संभवतः, यदि ओपी केवल ".pdf" फाइलें चाहता है, तो एक्सटेंशन के बिना फ़ाइलों को भी हटा दिया जाना चाहिए और अनदेखा नहीं किया जाना चाहिए।
डेनिस विलियमसन

1
यह दृष्टिकोण स्वीकृत उत्तर की तुलना में सरल और निरर्थक है।
पीटर

18

कचरा हटाएं :

$ cd <the directory you want>
$ gvfs-trash !(*.pdf)

या mvकमांड के माध्यम से (लेकिन इस तरह से आप इसे ट्रैश से पुनर्स्थापित नहीं कर सकते हैं क्योंकि यह रिकॉर्ड नहीं करता है .ashashinfo जानकारी, इसलिए इसका मतलब है कि आप अपनी फ़ाइलों को एक गंतव्य पर ले गए जहां यह निम्नानुसार है)।

mv !(*.pdf) ~/.local/share/Trash/files

6
यह दृष्टिकोण सीधे उपयोग करने की तुलना में अधिक सुरक्षित है rm
सेठ

14

सबसे आसान तरीका: कहीं और एक निर्देशिका बनाएँ (यदि आप केवल एक निर्देशिका में हटा रहे हैं, पुनरावृत्ति नहीं, तो यह एक उपनिर्देशिका भी हो सकती है); सभी .pdf के वहाँ जाएँ; सब कुछ हटा दें; पीडीएफ के पीछे हटो; मध्यवर्ती निर्देशिका हटाएं।

त्वरित, आसान, आप वही देख सकते हैं जो आप कर रहे हैं। बस सुनिश्चित करें कि मध्यवर्ती निर्देशिका उसी डिवाइस पर है जिस निर्देशिका को आप साफ कर रहे हैं ताकि चालें नाम बदलें, प्रतियां नहीं!


4
+1 फिर से एक टिप्पणी के लिए जो नौसिखिए उपयोगकर्ता के लिए समझ में आता है, जो लगभग निश्चित रूप से फ़ाइलों को अनजाने में हटाने का परिणाम नहीं होगा।
ट्रिगमेंन्डर्स 18

4

बैश के ग्लोब डिज़ाइनर का उपयोग करें:

GLOBIGNORE=x.pdf:a.pdf
rm *
unset GLOBIGNORE

बैश के मैन पेज से:

GLOBIGNORE:

            सेट को परिभाषित करने वाले पैटर्नों की एक अलग-अलग सूची
            फ़ाइल नाम का पथ नाम विस्तार द्वारा अनदेखा किया जाना है।

एक त्वरित परीक्षण:

mkdir /tmp/foooooo
cd /tmp/foooooo
touch x.pdf y.zip z.mp3 a.pdf
GLOBIGNORE=x.pdf:a.pdf
ls -1 *

आउटपुट:

y.zip
z.mp3

3

सावधान रहें और लिखें: xargs का उपयोग करें

यहां एक दृष्टिकोण है जो मुझे पसंद है, क्योंकि यह मुझे बहुत सावधान रहने देता है: केवल उन फ़ाइलों को दिखाने का एक तरीका लिखें, जिन्हें मैं हटाना चाहता हूं, फिर उन्हें rmउपयोग करने के लिए भेजें xargs। उदाहरण के लिए:

  • ls मुझे सब कुछ दिखाता है
  • ls | grep pdfमुझे उन फ़ाइलों को दिखाता है जिन्हें मैं रखना चाहता हूं। हम्म।
  • ls | grep -v pdfइसके विपरीत दिखाता है: सभी को छोड़कर जो मैं रखना चाहता हूं। दूसरे शब्दों में, यह उन चीजों की सूची दिखाता है जिन्हें मैं हटाना चाहता हूं। मैं कुछ भी खतरनाक करने से पहले इसकी पुष्टि कर सकता हूं।
  • ls | grep -v pdf | xargs rmrmहटाने के लिए वास्तव में वह सूची भेजता है

जैसा कि मैंने कहा, मुझे मुख्य रूप से सुरक्षा के लिए यह पसंद है: यह rm *मेरे लिए कोई आकस्मिक नहीं है। दो अन्य फायदे:

  • यह रचना योग्य है; आप अपनी पसंद के अनुसार प्रारंभिक सूची का उपयोग lsया findप्राप्त कर सकते हैं। आप उस सूची को संकीर्ण करने की प्रक्रिया में अपनी पसंद के अनुसार कुछ और उपयोग कर सकते हैं - दूसरा grep, कुछ awk, या जो भी। यदि आपको केवल उन फ़ाइलों को हटाने की आवश्यकता है जिनके नाम में एक रंग है, तो आप इसे उसी तरह से बना सकते हैं।
  • आप प्रत्येक उपकरण को उसके मुख्य उद्देश्य के लिए उपयोग कर सकते हैं। मैं findखोजने के लिए और rmहटाने के लिए उपयोग करना पसंद करता हूं , जैसा कि यह याद रखने के लिए कि झंडा findस्वीकार करता है -delete। और यदि आप ऐसा करते हैं, तो फिर से, आप वैकल्पिक समाधान लिख सकते हैं; शायद इसके बजाय rm, आप एक ऐसी trashकमांड बना सकते हैं जो फ़ाइल को कूड़ेदान में ले जाती है ("असमानता" की अनुमति देता है) और इसके बजाय पाइप rm। आपको findउस विकल्प का समर्थन करने की आवश्यकता नहीं है , आप इसे केवल पाइप करते हैं।

अपडेट करें

कुछ बढ़त के मामलों को संभालने के लिए इसे संशोधित करने के लिए @pabouk द्वारा टिप्पणियां देखें, जैसे फ़ाइल नामों में लाइन ब्रेक, फ़ाइल नाम जैसे my_pdfs.zip


4
मैंने यहां तीन समस्याओं पर ध्यान दिया: क)pdf इसके नाम में कहीं भी कोई भी फ़ाइल शामिल नहीं होगी । --- b) यदि प्रत्यय में कोई भी अक्षर ऊपरी स्थिति में है, तो यह पीडीएफ फाइलों को हटा देगा। --- c) आउटपुट का उपयोग करना अच्छा विचार नहीं है ls। यह नए नाम वाली फ़ाइल नामों के साथ काम नहीं करेगा। lsविशेष वर्णों को प्रतिस्थापित करने के कुछ कार्यान्वयन जैसे कि टैब द्वारा ?। --- इसका उपयोग करना बेहतर है find -maxdepth 1 -print0:। (इतना छोटा नहीं है ls:) ----- को हल करने के लिए a) और b) का उपयोग करें grep -vi '\.pdf$'--- पूर्ण (लेकिन केवल GNU) समाधान:find -maxdepth 1 -print0 | grep -viz '\.pdf$' | xargs -0 rm
pabouk

1
मैं समझता हूं कि आप कई मैनुअल पुनरावृत्तियों के साथ एक "इंटरएक्टिव" प्रक्रिया के रूप में समाधान का मतलब है, लेकिन चेक फ़ाइलों की लंबी सूची के लिए शायद ही प्रयोग करने योग्य होगा और ऊपर बताई गई समस्याएं गलतियों को अनदेखा करने में आसान ला सकती हैं।
पाबौक

1
@pabouk अच्छे अंक; वास्तविक दुनिया हमेशा चीजों को जटिल बनाती है, और आपके सुधार सहायक होते हैं। :) लेकिन मुझे अभी भी लगता है कि यह समग्र दृष्टिकोण सबसे अच्छा है। यदि हर चीज की दृष्टि से पुष्टि करने के लिए बहुत सारी फाइलें हैं, तो आप | head -20कम से कम यह देख सकते हैं कि क्या यह लगभग सही दिखता है, जबकि यदि आप बस rm my_pattern, तो आपके पास कोई बड़ी गलती करने का कोई मौका नहीं है।
नाथन लॉन्ग

1
आप उन्हें डिलीट करने से पहले फ़ाइलों को दिखा सकते हैं, -delete को छोड़ दें और बस find . -type f ! -name "*.pdf"कंसोल को प्रिंट करने के लिए उपयोग करें, या कम या किसी फ़ाइल को पाइप करने के लिए। [और फिर pabouk की टिप्पणी (-प्रिंट0 के साथ वांछित ... - -0 अजीब फ़ाइल नाम के लिए) की तरह rm करने के लिए xargs करने के लिए पाइप]
Xen2050 7

3

मैं आमतौर पर इंटरैक्टिव पायथन इंटरप्रेटर से ऐसी समस्याओं को हल करता हूं:

mic@mic ~ $ python
>>> import os
>>> for f in os.listdir('.'):
...   if not f.endswith('.pdf'):
...     os.remove(f)

यह एक-लाइनर के साथ findया उससे अधिक लंबा हो सकता है xargs, लेकिन यह बहुत लचीला है, और मुझे पता है कि यह वास्तव में क्या करता है, इसके बारे में पहले शोध किए बिना।


उन लोगों के लिए जो हर अतिरिक्त लाइन से घबरा जाते हैं, हम इसे एक बना सकते हैं:for item in [f for f in os.listdir('.') if not f.endswith('.pdf')]: os.remove(item)
याकूब Vlijm

python -c "import os; for f in os.listdir('.'): if not f.endswith('.pdf'): os.remove(f)"
mic_e

[os.remove(f) for f in os.listdir('.') if not f.endswith('.pdf')]
mic_e

अच्छा! दूसरा मुझे एक सिंटैक्स त्रुटि देता है, यह मत देखें कि क्यों।
जैकब व्लिजम

अजीब; यह मेरे सिस्टम पर अजगर 3.4 और अजगर 2.7 दोनों के साथ काम करता है।
mic_e

2

इस प्रश्न का बेहतर उत्तर (मेरे पिछले उत्तर की तुलना में) शक्तिशाली fileकमांड का उपयोग करके होगा ।

$ file -i abc.pdf
abc: application/pdf; charset=binary

अब आपकी समस्या:

cd <the directory you want to search in>
for var in ./*
do
if file -i "$var" | grep -q 'application/pdf\;'
then
echo "$var"
fi
done

forकमांड का काम चर के रूप में वर्तमान निर्देशिका में फाइलें देता है $varif-thenकमांड , कमांड 0से बाहर निकलने की स्थिति लेकर पीडीएफ फाइलों के नाम को आउटपुट करता है file -i "$var" | grep -q 'application/pdf\;', यह 0केवल तभी बाहर निकलने की स्थिति देगा, जब यह पीडीएफ फाइलें ढूंढता है।


1
rm $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')

चेतावनी! पहले बेहतर प्रयास करें

ls -l $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')

2
उह, यह इतने तरीकों से त्रुटिपूर्ण है: smallo.ruhr.de/award.html#ls , smallo.ruhr.de/award.html#grep , और यह पूरी तरह से सफेद स्थान या विशेष वर्णों के साथ फ़ाइल नामों को अनदेखा करता है।
डेविड फ़ॉस्टर

1
आप वास्तव में उपयोग करना चाहिए -iसाथ grepकेस-संवेदी मिलान के लिए।
मुरु

1
rm -i -- !(*@(a|x).pdf)

के रूप में पढ़ें, सभी फ़ाइलों को हटा दें जो नहीं हैं a.pdfया नहीं x.pdf

यह 2 विस्तारित ग्लब्स का उपयोग करके काम करता है, बाहरी !()में निहित ग्लोब को नकारने के लिए जो स्वयं की आवश्यकता है कि ग्लोब को प्रत्यय से पहले एक या अधिक aया xपैटर्न से मेल खाना चाहिए .pdfग्लोब # एक्सग्लोब देखें ।

$ ls -a
.dotfile1 .dotfile2 a.pdf x.pdf y.zip z.mp3

$ echo -- !(a.pdf)
-- x.pdf y.zip z.mp3

$ echo -- !(x.pdf)
-- a.pdf y.zip z.mp3

$ echo -- !(a.pdf|x.pdf)
-- y.zip z.mp3

$ echo -- !(@(a|x).pdf)   # NOTE.that this matches the .dotfiles* as well
-- . .. .dotfile1 .dotfile2 y.zip z.mp3

$ echo -- !(*@(a|x).pdf)  # but this doesn't
-- y.zip z.mp3

$ echo rm -i -- !(*@(a|x).pdf)
rm -i -- y.zip z.mp3

1

पोर्टेबल शेल तरीका

$ ksh -c 'for i in ./*; do case $i in *.pdf)continue;; *)rm "$i";; esac;done'

काफी POSIX और किसी भी बॉर्न शैली खोल के साथ संगत ( ksh, bash, dash)। अच्छी तरह से पोर्टेबल लिपियों के लिए उपयुक्त है और जब आप bashखोल के गोलाबारी का उपयोग नहीं कर सकते ।

पर्ल:

$ perl -le 'opendir(my $d,"."); foreach my $f (grep(-f && !/.pdf/ , readdir($d))){unlink $f};closedir $d'                                                             

या थोड़ा क्लीनर:

$ perl -le 'opendir(my $d,"."); map{ unlink $_ } grep(-f "./$_" && !/.pdf/ , readdir($d));closedir $d'

वैकल्पिक अजगर

python -c 'import os;map(lambda x: os.remove(x), filter(lambda x: not x.endswith(".pdf"),os.listdir(".")))'

0

आप जो हटा रहे हैं उससे सावधान रहें!

हटाने की कोशिश करने से पहले इसका परीक्षण करने का एक सुरक्षित तरीका यह है कि पहले परीक्षण किया जाए ls, क्योंकि कुछ अनकहे व्यवहार अवांछित फ़ाइलों को हटा सकते हैं। और आप इसे सीधे डायरेक्ट्री के बाहर कर सकते हैं। lsके समान है rm, इसलिए:

ls sub/path/to/files/!(*.pdf)

यह सूची होगी

y.zip
z.mp3

और अब आप देख सकते हैं कि आप क्या हटा रहे हैं और उन्हें सुरक्षित रूप से हटा सकते हैं:

rm sub/path/to/files/!(*.pdf)

और बस। यो वाइल्डकार्ड *का उपयोग करने के लिए और अधिक चयनात्मक हो सकता है जैसे कि केवल प्रोग्रामिंग कोर्स दस्तावेज रखना:

rm sub/path/to/files/!(*programming*)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.