Menghapus semua file dalam folder kecuali file X, Y, dan Z

17

Saya memiliki banyak file dan folder di folder tertentu dan saya ingin menghapus semuanya; Namun, saya ingin menyimpan file X, Y, dan Z.

Apakah ada cara saya bisa melakukan sesuatu seperti: rm * | but NOT grep | X or Y or Z

Amit
sumber
Saya berasumsi saya dapat menggunakan beberapa ekspresi reguler di sana yang akan melakukan ini?
Amit

Jawaban:

16

Alih-alih menggunakan rm, mungkin lebih mudah digunakan find . Perintah seperti ini akan menghapus semuanya kecuali file yang bernama persis 'file'

find . \! -name 'file' -delete

Banyak versi harus dapat mendukung globbing dan pencocokan ekspresi reguler.

Anda juga bisa menyalurkan output find ke rm juga

find . \! -name '*pattern*' -print0 | xargs --null rm 
Sakit kepala
sumber
3
Dan ini memungkinkan Anda melihat persis file apa yang akan dihapus dengan menghapus -deleteserta file apa yang akan disimpan dengan menghapus -deletedan \!.
Shawn J. Goff
1
hati-hati, findbersifat rekursif! jadi semua file subdirektori yang tidak cocok dengan ' pola ' juga akan dihapus
Alexandre Holden Daly
Cara melalui xargs perlu -depth, untuk mencegah upaya menghapus direktori sebelum file dimasukkan di dalamnya. Namun, saya pikir rm juga tidak akan menghapus direktori.
pengguna tidak diketahui
9

Menggunakan zsh, dengan setopt EXTENDED_GLOB, menggunakan ~operator ( kecuali )

rm -- *~(x|y|z)

atau ^operator (negasi):

rm -- ^(x|y|z)

Tapi, Anda mungkin harus memindahkan file di tempat lain, lalu hapus semuanya. Ini jauh lebih aman dalam hal slip jari, seperti memukul masuk terlalu cepat.

Wnoise
sumber
5

Versi bash yang lebih baru memiliki extglobopsi shell yang memberi Anda sintaks untuk melakukan apa yang Anda inginkan (periksa halaman manual Anda di bawah "Pathname Expansion" untuk melihat apakah versi yang diinstal memilikinya):

$ shopt -s extglob  # turn on extended globbing
$ rm !(X|Y|Z)

Untuk menguji, saya sarankan Anda ganti dulu rmdengan echountuk melihat apakah daftar file yang akan dihapus adalah apa yang Anda harapkan.

camh
sumber
5
ls -1 | grep -v "^[XYZ]$" # | xargs rm -r

Perhatian: Jalankan perintah dan jika file yang akan dihapus adalah yang benar, jalankan lagi dan hapus karakter hash "#".

Jika nama file lebih rumit dari itu, lakukan

ls -1 | egrep -v "^file1$|^filename2$|^f1le$" # | xargs rm -r

Sekali lagi, pertama lihat hasilnya kemudian hapus tanda hash.

Versi ini - seperti yang disarankan dalam komentar - menyimpan beberapa karakter dan terlihat sedikit lebih jelas.

ls -1 | egrep -v "^(file1|filename2|f1le)$" # | xargs rm -r
ddeimeke
sumber
Suntingan yang disarankan oleh ddeimeke adalah mengubah egrepargumen ke"^(file1|filename2|f1le)$"
Michael Mrozek
Jika Anda memiliki tiga file a, bdan a bprogram pertama akan menghapus - jika Anda memasukkan ab ke dalam bagian grep: "^[ab]$" adan btetapi tidak a b, lawan saja dari niat Anda. Perintah kedua akan melakukan hal yang sama. Dan yang ketiga juga. Anda seharusnya tidak menggunakan 'ls' dalam skrip, dengan pengecualian yang sangat, sangat jarang. Tapi jangan lakukan itu.
pengguna tidak diketahui
3

Pindahkan file yang ingin Anda simpan. Naik satu tingkat, hapus folder. Buat kembali folder dan pindahkan file-file itu kembali.

alex
sumber
Saya bertanya-tanya mengapa minus? .. Ini sebenarnya lebih mudah dan lebih aman daripada apa pun yang diusulkan oleh orang lain: Anda tidak bisa menembak diri sendiri dengan memukul beberapa karakter khusus dalam nama file.
alex
a) Anda memindahkan file X satu direktori ke atas, tempat file X ada - terhapus secara diam-diam, hilang. b) Anda berada di dir atas, di mana tidak ada 'naik'. c) Anda di rumah Anda , dan tidak memiliki izin untuk menulis ke / rumah. Jika Anda memasukkan saran Anda ke dalam skrip, dan mengujinya tanpa masalah, dan menggunakannya dalam situasi seperti itu - peng!
pengguna tidak diketahui
2
a) Hei, apakah saya mengatakan 'pindahkan file ke atas satu tingkat'? Saya sudah mengatakan memindahkan mereka. b) Jadi kamu mencoba untuk menghapus semua file /, heh? Tidak terlalu praktis. c) Mencoba menghapus semua file di komputer Anda $HOMEjuga tidak terlalu praktis.
alex
Anda benar, saya minta maaf.
pengguna tidak dikenal
0

Ini yang saya atur sebagai skrip .sh untuk kait logout OSX / MacOS, berfungsi cukup baik.

#! /bin/bash
for dir in /PathToFolder/*
 do
    if [ ! "$dir" = "/PathToFolder/FolderToKeep1" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep2" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep3" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep4" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep5" ] && [ ! "$dir" = "/PathToFolder/FolderToKeep6" ] ; then 
      echo ${dir}
      sudo rm -R $dir user
      dscl . -delete $dir
    fi 
  done

exit 0
ICMP
sumber
0

Dengan GNU-find Anda dapat menggunakan -delete switch, yang menghapus direktori, jika kosong juga:

 find tmp -not -name X -not -name Y -not -name Z -delete 
Pengguna tidak diketahui
sumber
Jika X, Y atau Z adalah direktori, ini juga akan menghapus file di dalamnya. find tmp -maxdepth 1 -not -name X -not -name Y -not -name Z -deleteadalah salah satu cara untuk mengatasi ini.
Gilles 'SO- berhenti bersikap jahat'
Karena folder di bawah Unix adalah file (apa pun itu file), itulah yang mungkin dimaksudkan. Pertanyaannya secara eksplisit mengatakan: "Saya memiliki banyak file dan folder di folder tertentu dan saya ingin menghapus semuanya;" - dan jika Anda ingin mengecualikan Y, mungkin Anda tahu apakah Y adalah direktori atau tidak.
pengguna tidak diketahui
Itu akan berakhir dengan menghapus tmpjuga jika tidak ada X/ Y/ Zfile di dalamnya. Catatan !sebagai standar yang setara dengan GNU -not( -deletejuga merupakan ekstensi GNU)
Stéphane Chazelas
@ StéphaneChazelas: Dari pertanyaan, menghapus folder (semuanya) adalah yang diminta. Karena bang perlu ditutup, saya lebih suka mengetik -tidak. Mungkin tergantung pada tata letak keyboard Jerman, di mana Backslash membutuhkan Alt-Gr.
pengguna tidak diketahui