Jawaban:
cd <the directory you want>
find . -type f ! -iname "*.pdf" -delete
.pdfnama fileMisalnya, jika ada direktori yang dipanggil tempdi folder rumah Anda:
cd ~/temp
lalu hapus file:
find . -type f ! -iname "*.pdf" -delete
Ini akan menghapus semua file kecuali xyz.pdf.
Anda dapat menggabungkan dua perintah ini untuk:
find ~/temp -type f ! -iname "*.pdf" -delete
.adalah direktori saat ini. !berarti mengambil semua file kecuali yang ada .pdfdi akhir. -type fhanya memilih file, bukan direktori. -deleteberarti menghapusnya.
!harus datang sebelumnya -name. hanya -nameakan mencakup saja .pdf, sementara -inameakan mencakup keduanya .pdfdan.PDFUntuk menghapus hanya di direktori saat ini dan tidak di sub-direktori tambahkan -maxdepth 1:
find . -maxdepth 1 -type f ! -iname "*.pdf" -delete
.berarti direktori saat ini. !artinya mengambil semua file kecuali yang ada .pdfdi akhir. -deleteberarti menghapusnya. apakah saya jelas sekarang?
-maxdepth 1parameter untuk memulai. Kemudian sarankan untuk menghapus parameter jika seseorang ingin menghapus secara rekursif.
Dengan bashperpanjangan shell, Anda bisa menghapus file apa pun dengan ekstensi selain .pdfmenggunakan
rm -- *.!(pdf)
Sebagaimana dicatat oleh @pts, --karakter menunjukkan akhir dari opsi perintah apa pun, membuat perintah aman dalam kasus yang jarang terjadi dari file yang namanya dimulai dengan -karakter.
Jika Anda ingin menghapus file tanpa ekstensi apa pun serta ekstensi selain .pdf, maka seperti yang ditunjukkan oleh @DennisWilliamson, Anda dapat menggunakan
rm -- !(*.pdf)
Perpanjangan globbing harus diaktifkan secara default, tetapi jika tidak Anda dapat melakukannya dengan menggunakan
shopt -s extglob
Terutama jika Anda berniat untuk menggunakan ini di dalam skrip, penting untuk dicatat bahwa jika ekspresi tidak cocok dengan apa pun (yaitu jika tidak ada file non-pdf dalam direktori), maka secara default glob akan diteruskan tidak diperluas ke rmperintah, menghasilkan kesalahan seperti
rm: cannot remove `*.!(pdf)': No such file or directory
Anda dapat mengubah perilaku default ini menggunakan nullglobopsi shell, namun itu memiliki masalah sendiri. Untuk diskusi yang lebih menyeluruh lihat NullGlob - Greg's Wiki
rm *~*.pdf
!(*.py). Juga, mungkin, jika OP hanya menginginkan file ".pdf" tersisa, maka file tanpa ekstensi juga harus dihapus dan tidak diabaikan.
$ cd <the directory you want>
$ gvfs-trash !(*.pdf)
Atau melalui mvperintah (tetapi dengan cara ini Anda tidak dapat mengembalikannya dari Sampah karena tidak merekam informasi .trashinfo, jadi ini berarti Anda memindahkan file Anda ke tujuan di mana itu adalah sebagai berikut).
mv !(*.pdf) ~/.local/share/Trash/files
rm.
Pendekatan termudah: Buat direktori lain di suatu tempat (jika Anda hanya menghapus dalam satu direktori, tidak secara rekursif, itu bahkan bisa menjadi subdirektori); pindahkan semua .pdf di sana; hapus yang lainnya; pindahkan kembali pdf; hapus direktori perantara.
Cepat, mudah, Anda dapat melihat apa yang Anda lakukan. Pastikan direktori perantara ada di perangkat yang sama dengan direktori yang Anda bersihkan sehingga gerakannya adalah penggantian nama, bukan salinan!
Gunakan bash's GLOBIGNORE:
GLOBIGNORE=x.pdf:a.pdf
rm *
unset GLOBIGNORE
Dari halaman manual bash:
GLOBIGNORE:
Daftar pola yang dipisahkan titik dua yang mendefinisikan set
nama file yang akan diabaikan oleh ekspansi pathname.
Tes cepat:
mkdir /tmp/foooooo
cd /tmp/foooooo
touch x.pdf y.zip z.mp3 a.pdf
GLOBIGNORE=x.pdf:a.pdf
ls -1 *
Keluaran:
y.zip z.mp3
Berikut ini pendekatan yang saya sukai, karena ini membuat saya sangat berhati-hati: menulis cara untuk menunjukkan file yang ingin saya hapus, kemudian mengirimkannya untuk rmdigunakan xargs. Sebagai contoh:
ls Tunjukkan semuanyals | grep pdfmenunjukkan kepada saya file yang ingin saya simpan. Hmm.ls | grep -v pdfmenunjukkan yang sebaliknya: semua kecuali yang ingin saya simpan. Dengan kata lain, ini menunjukkan daftar hal yang ingin saya hapus. Saya dapat mengkonfirmasi ini sebelum melakukan sesuatu yang berbahaya.ls | grep -v pdf | xargs rmmengirimkan daftar itu ke rmuntuk dihapusSeperti yang saya katakan, saya terutama suka ini untuk keselamatan yang disediakannya: tidak disengaja rm *bagi saya. Dua keuntungan lain:
lsatau finduntuk mendapatkan daftar awal, seperti yang Anda inginkan. Anda dapat menggunakan apa pun yang Anda suka dalam proses mempersempit daftar itu - yang lain grep, beberapa awk, atau apa pun. Jika Anda hanya perlu menghapus file yang namanya mengandung warna, Anda dapat membuatnya dengan cara yang sama.finduntuk menemukan dan rmuntuk menghapus, daripada harus ingat yang findmenerima -deletebendera. Dan jika Anda melakukan ini, sekali lagi, Anda dapat membuat solusi alternatif; mungkin alih-alih rm, Anda bisa membuat trashperintah yang memindahkan file ke tempat sampah (memungkinkan "undeletion") dan menyalurkannya ke sana rm. Anda tidak perlu memiliki finddukungan opsi itu, Anda hanya perlu melakukannya.Lihat komentar oleh @pabouk untuk bagaimana memodifikasi ini untuk menangani beberapa kasus tepi, seperti jeda baris dalam nama file, nama file seperti my_pdfs.zip, dll.
pdfnamanya. --- b) Ini akan menghapus file PDF jika salah satu huruf dalam sufiks adalah huruf besar. --- c) Bukan ide yang baik untuk menggunakan output dari ls. Itu tidak akan bekerja dengan nama file yang mengandung baris baru. Beberapa implementasi lsganti karakter khusus misalnya tab oleh ?. --- Lebih baik untuk digunakan: find -maxdepth 1 -print0. (tidak sesingkat ls:) ----- Untuk menyelesaikan a) dan b) gunakan grep -vi '\.pdf$'--- solusi lengkap (tapi hanya GNU):find -maxdepth 1 -print0 | grep -viz '\.pdf$' | xargs -0 rm
| head -20setidaknya melihat apakah itu terlihat benar, sedangkan jika Anda hanya rm my_pattern, Anda tidak memiliki kesempatan untuk menemukan kesalahan besar.
find . -type f ! -name "*.pdf"untuk mencetak ke konsol, atau pipa ke file yang lebih sedikit atau. [dan kemudian pipa ke xargs ke rm jika diinginkan seperti komentar pabouk (dengan -print0 | ... -0 untuk nama file yang aneh)]
Saya biasanya memecahkan masalah seperti itu dari juru bahasa Python interaktif:
mic@mic ~ $ python
>>> import os
>>> for f in os.listdir('.'):
... if not f.endswith('.pdf'):
... os.remove(f)
Mungkin lebih lama dari satu-liner dengan findatau xargs, tapi itu sangat ulet, dan saya tahu persis apa yang dilakukannya, tanpa harus melakukan riset terlebih dahulu.
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')]
jawaban yang lebih baik (dibandingkan dengan jawaban saya sebelumnya) untuk pertanyaan ini adalah dengan menggunakan fileperintah yang kuat .
$ file -i abc.pdf
abc: application/pdf; charset=binary
sekarang masalahmu:
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
tugas dari forperintah adalah memberikan file dalam direktori saat ini dalam bentuk variabel $var. if-thenperintah menampilkan nama-nama file pdf dengan mengambil status keluar 0dari file -i "$var" | grep -q 'application/pdf\;'perintah, itu akan memberikan status keluar 0hanya jika menemukan file pdf.
rm $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')
Peringatan! Lebih baik coba dulu
ls -l $(ls -lo|grep -v [Pp][Dd][Ff]$|awk '{print $7}')
-idengan grepuntuk pencocokan case-sensitive.
rm -i -- !(*@(a|x).pdf)
Baca sebagai, hapus semua file yang bukan a.pdfatau x.pdf.
Ini bekerja dengan memanfaatkan 2 gumpalan diperpanjang, bagian luar !()untuk meniadakan gumpalan terkandung yang dengan sendirinya mengharuskan gumpalan harus cocok dengan satu atau lebih dari aatau xpola sebelum .pdfsufiks. Lihat glob # extglob .
$ 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'
Cukup banyak POSIX dan kompatibel dengan Bourne-gaya shell ( ksh, bash, dash). Sangat cocok untuk skrip portabel dan ketika Anda tidak dapat menggunakan bashglobbing shell diperpanjang.
$ perl -le 'opendir(my $d,"."); foreach my $f (grep(-f && !/.pdf/ , readdir($d))){unlink $f};closedir $d'
Atau sedikit lebih bersih:
$ 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(".")))'
Berhati-hatilah dengan apa yang Anda hapus!
Cara aman untuk mengujinya sebelum mencoba menghapus adalah mengujinya terlebih dahulu ls, karena beberapa perilaku yang tidak tertangkap dapat menghapus file yang tidak diinginkan. Dan Anda dapat melakukannya langsung di luar direktori. lsmirip dengan rm, jadi:
ls sub/path/to/files/!(*.pdf)
Ini akan mencantumkan
y.zip
z.mp3
Dan sekarang Anda dapat melihat apa yang Anda hapus dan dapat menghapusnya dengan aman:
rm sub/path/to/files/!(*.pdf)
Dan itu saja. Anda dapat menggunakan wildcard *untuk menjadi lebih selektif seperti hanya menyimpan dokumen kursus pemrograman:
rm sub/path/to/files/!(*programming*)
.berarti "dan"?!berarti "kecuali"-namemenandakan bahwa Anda ingin mengecualikan dengan parameter nama dan kemudian-deleteadalah tindakan yang harus diambil setelah menemukan? Jadi mencari semuanya kecuali "* .pdf" dan menghapusnya? Atau apakah saya salah paham?