जवाबों:
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
.
वर्तमान निर्देशिका का मतलब है। अंत के !
साथ एक को छोड़कर सभी फ़ाइलों को लेने का मतलब है .pdf
। -delete
इसे हटाने का मतलब है। क्या मैं अब स्पष्ट हूँ?
-maxdepth 1
शुरू करने के लिए पैरामीटर को शामिल करना चाहिए । फिर एक पुनरावर्ती को हटाना चाहता है मामले में पैरामीटर को हटाने का सुझाव दें।
साथ bash
'विस्तारित खोल ग्लोबिंग है, आप के अलावा अन्य एक्सटेंशन के साथ किसी भी फाइल को दूर कर सकता है .pdf
का उपयोग करते हुए
rm -- *.!(pdf)
जैसा कि @pts द्वारा उल्लेख किया गया है, --
वर्ण किसी भी कमांड विकल्प के अंत को इंगित करते हैं, कमांड को फाइलों के दुर्लभ मामले में सुरक्षित बनाते हैं, जिनके नाम एक -
चरित्र से शुरू होते हैं ।
यदि आप फ़ाइलों को बिना किसी एक्सटेंशन के और साथ ही उन एक्सटेंशनों के साथ हटाना चाहते हैं .pdf
, तो जैसा कि @DennisWilliams द्वारा बताया गया है, जिसका आप उपयोग कर सकते हैं
rm -- !(*.pdf)
विस्तारित ग्लोबिंग को डिफ़ॉल्ट रूप से सक्षम किया जाना चाहिए, लेकिन यदि आप ऐसा उपयोग नहीं कर सकते हैं
shopt -s extglob
खासकर यदि आप इसे एक स्क्रिप्ट के अंदर उपयोग करने का इरादा रखते हैं, तो यह ध्यान रखना महत्वपूर्ण है कि यदि अभिव्यक्ति कुछ भी मेल नहीं खाती है (अर्थात यदि निर्देशिका में कोई गैर-पीडीएफ फाइलें नहीं हैं), तो डिफ़ॉल्ट रूप से ग्लोब को अनएक्सपेक्टेड पास किया जाएगा rm
कमांड, जैसे त्रुटि
rm: cannot remove `*.!(pdf)': No such file or directory
आप nullglob
शेल विकल्प का उपयोग करके इस डिफ़ॉल्ट व्यवहार को संशोधित कर सकते हैं , हालांकि इसका अपना मुद्दा है। अधिक गहन चर्चा के लिए नलग्लोब - ग्रेग का विकी देखें
rm *~*.pdf
!(*.py)
:। इसके अलावा, संभवतः, यदि ओपी केवल ".pdf" फाइलें चाहता है, तो एक्सटेंशन के बिना फ़ाइलों को भी हटा दिया जाना चाहिए और अनदेखा नहीं किया जाना चाहिए।
$ cd <the directory you want>
$ gvfs-trash !(*.pdf)
या mv
कमांड के माध्यम से (लेकिन इस तरह से आप इसे ट्रैश से पुनर्स्थापित नहीं कर सकते हैं क्योंकि यह रिकॉर्ड नहीं करता है .ashashinfo जानकारी, इसलिए इसका मतलब है कि आप अपनी फ़ाइलों को एक गंतव्य पर ले गए जहां यह निम्नानुसार है)।
mv !(*.pdf) ~/.local/share/Trash/files
rm
।
सबसे आसान तरीका: कहीं और एक निर्देशिका बनाएँ (यदि आप केवल एक निर्देशिका में हटा रहे हैं, पुनरावृत्ति नहीं, तो यह एक उपनिर्देशिका भी हो सकती है); सभी .pdf के वहाँ जाएँ; सब कुछ हटा दें; पीडीएफ के पीछे हटो; मध्यवर्ती निर्देशिका हटाएं।
त्वरित, आसान, आप वही देख सकते हैं जो आप कर रहे हैं। बस सुनिश्चित करें कि मध्यवर्ती निर्देशिका उसी डिवाइस पर है जिस निर्देशिका को आप साफ कर रहे हैं ताकि चालें नाम बदलें, प्रतियां नहीं!
बैश के ग्लोब डिज़ाइनर का उपयोग करें:
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
यहां एक दृष्टिकोण है जो मुझे पसंद है, क्योंकि यह मुझे बहुत सावधान रहने देता है: केवल उन फ़ाइलों को दिखाने का एक तरीका लिखें, जिन्हें मैं हटाना चाहता हूं, फिर उन्हें rm
उपयोग करने के लिए भेजें xargs
। उदाहरण के लिए:
ls
मुझे सब कुछ दिखाता हैls | grep pdf
मुझे उन फ़ाइलों को दिखाता है जिन्हें मैं रखना चाहता हूं। हम्म।ls | grep -v pdf
इसके विपरीत दिखाता है: सभी को छोड़कर जो मैं रखना चाहता हूं। दूसरे शब्दों में, यह उन चीजों की सूची दिखाता है जिन्हें मैं हटाना चाहता हूं। मैं कुछ भी खतरनाक करने से पहले इसकी पुष्टि कर सकता हूं।ls | grep -v pdf | xargs rm
rm
हटाने के लिए वास्तव में वह सूची भेजता हैजैसा कि मैंने कहा, मुझे मुख्य रूप से सुरक्षा के लिए यह पसंद है: यह rm *
मेरे लिए कोई आकस्मिक नहीं है। दो अन्य फायदे:
ls
या find
प्राप्त कर सकते हैं। आप उस सूची को संकीर्ण करने की प्रक्रिया में अपनी पसंद के अनुसार कुछ और उपयोग कर सकते हैं - दूसरा grep
, कुछ awk
, या जो भी। यदि आपको केवल उन फ़ाइलों को हटाने की आवश्यकता है जिनके नाम में एक रंग है, तो आप इसे उसी तरह से बना सकते हैं।find
खोजने के लिए और rm
हटाने के लिए उपयोग करना पसंद करता हूं , जैसा कि यह याद रखने के लिए कि झंडा find
स्वीकार करता है -delete
। और यदि आप ऐसा करते हैं, तो फिर से, आप वैकल्पिक समाधान लिख सकते हैं; शायद इसके बजाय rm
, आप एक ऐसी trash
कमांड बना सकते हैं जो फ़ाइल को कूड़ेदान में ले जाती है ("असमानता" की अनुमति देता है) और इसके बजाय पाइप rm
। आपको find
उस विकल्प का समर्थन करने की आवश्यकता नहीं है , आप इसे केवल पाइप करते हैं।कुछ बढ़त के मामलों को संभालने के लिए इसे संशोधित करने के लिए @pabouk द्वारा टिप्पणियां देखें, जैसे फ़ाइल नामों में लाइन ब्रेक, फ़ाइल नाम जैसे my_pdfs.zip
।
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
| head -20
कम से कम यह देख सकते हैं कि क्या यह लगभग सही दिखता है, जबकि यदि आप बस rm my_pattern
, तो आपके पास कोई बड़ी गलती करने का कोई मौका नहीं है।
find . -type f ! -name "*.pdf"
कंसोल को प्रिंट करने के लिए उपयोग करें, या कम या किसी फ़ाइल को पाइप करने के लिए। [और फिर pabouk की टिप्पणी (-प्रिंट0 के साथ वांछित ... - -0 अजीब फ़ाइल नाम के लिए) की तरह rm करने के लिए xargs करने के लिए पाइप]
मैं आमतौर पर इंटरैक्टिव पायथन इंटरप्रेटर से ऐसी समस्याओं को हल करता हूं:
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)
python -c "import os; for f in os.listdir('.'): if not f.endswith('.pdf'): os.remove(f)"
[os.remove(f) for f in os.listdir('.') if not f.endswith('.pdf')]
इस प्रश्न का बेहतर उत्तर (मेरे पिछले उत्तर की तुलना में) शक्तिशाली 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
कमांड का काम चर के रूप में वर्तमान निर्देशिका में फाइलें देता है $var
। if-then
कमांड , कमांड 0
से बाहर निकलने की स्थिति लेकर पीडीएफ फाइलों के नाम को आउटपुट करता है file -i "$var" | grep -q 'application/pdf\;'
, यह 0
केवल तभी बाहर निकलने की स्थिति देगा, जब यह पीडीएफ फाइलें ढूंढता है।
rm $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')
चेतावनी! पहले बेहतर प्रयास करें
ls -l $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')
-i
साथ grep
केस-संवेदी मिलान के लिए।
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
$ 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(".")))'
आप जो हटा रहे हैं उससे सावधान रहें!
हटाने की कोशिश करने से पहले इसका परीक्षण करने का एक सुरक्षित तरीका यह है कि पहले परीक्षण किया जाए 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*)
.
मतलब "और"?!
मतलब "को छोड़कर"-name
दर्शाता है कि आप एक नाम पैरामीटर द्वारा बाहर करना चाहते हैं और फिर-delete
खोजने पर कार्रवाई करना है? तो यह "* .pdf" को छोड़कर हर चीज की तलाश करता है और उन्हें हटा देता है? या मुझे गलत समझा है?