Hapus semua kecuali 1000 file acak dalam direktori

13

Saya membiarkan skrip pembuatan data berjalan terlalu lama sekarang memiliki 200.000 file yang saya butuhkan dikurangi menjadi sekitar 1000. Dari baris perintah Linux, apakah ada cara mudah untuk menghapus semua kecuali 1000 file ini, di mana file yang akan dipertahankan tidak akan memiliki ketergantungan pada nama file atau atribut lainnya?

Malcolm Regan
sumber
Apakah proses yang membuat file memiliki karakteristik yang menghubungkan setiap file dengan yang sebelumnya? Jika demikian, daripada memilih secara acak akan penting untuk mendapatkan sampel yang representatif. Jika proses tersebut menghasilkan file yang sifatnya acak, Anda bisa menghapus semuanya setelah 1000 pertama.
fixer1234

Jawaban:

15

Hapus semua kecuali 1000 file acak dalam direktori

Kode:

find /path/to/dir -type f -print0 | sort -zR | tail -zn +1001 | xargs -0 rm

Penjelasan:

  1. Daftar semua file /path/to/dirdengan find;
    • print0: gunakan \0( karakter nol ) sebagai pembatas garis; jadi jalur file yang berisi spasi / baris baru tidak merusak skrip
  2. Kocok daftar file dengan sort;
    • -z: gunakan \0(karakter nol) sebagai pembatas, alih-alih \n(baris baru)
    • -R: pesanan acak
  3. Lepaskan 1000 baris pertama dari daftar acak dengan tail;
    • -z: memperlakukan daftar sebagai nol-dibatasi (sama dengan dengan sort)
    • -n +1001: tampilkan baris mulai dari 1001 (mis. hilangkan 1000 baris pertama)
  4. xargs -0 rm - hapus file yang tersisa;
    • -0: nol-dibatasi, lagi

Mengapa lebih baik daripada solusi quixotic *:

  1. Bekerja dengan nama file yang mengandung spasi / baris baru.
  2. Tidak mencoba membuat direktori apa pun (yang mungkin sudah ada, btw.)
  3. Tidak memindahkan file apa pun, bahkan tidak menyentuh 1000 "file keberuntungan" selain mendaftarkannya find.
  4. Hindari kehilangan file jika output findtidak diakhiri dengan \n(baris baru) karena beberapa alasan.

* - kredit untuk quixotic untuk | sort -R | head -1000, memberi saya titik awal.

rld.
sumber
Berjalan di CentOS 6 Saya mendapatkan kesalahan tentang operan yang tidak valid. Untungnya saya tidak peduli dengan spasi di filepath jadi menghapus operan itu bekerja untuk sayafind . -type f | sort -R | tail -n +1001 | xargs rm
brad
@brad Bisakah Anda memberikan pesan kesalahan dan versi Anda find? Saya akan mencoba meningkatkan jawaban saya, hanya butuh beberapa masukan untuk bekerja dengannya.
rld.
3
tail: invalid option -- 'z'versi ekor yang saya miliki adalah 8,4
brad
Saya akan menambahkan --tidak-jalankan-jika-kosong ke xargs untuk menghindari kesalahan jika tidak ada file (setelah menjalankannya dua kali untuk contoh)
fraff
1

Gunakan direktori sementara, lalu findsemua file Anda, acak daftar dengan sort, dan pindahkan 1000 teratas daftar ke direktori sementara. Hapus sisanya, lalu pindahkan file kembali dari direktori sementara.

$ mkdir ../tmp-dir
$ find . -type f | sort -R | head -1000 | xargs -I "I" mv I ../tmp-dir/
$ rm ./*
$ mv ../tmp-dir/* .

Jika xargsmengeluh tentang panjang garis, menggunakan sejumlah kecil dengan headdan ulangi perintah yang diperlukan (yaitu, perubahan -1000ke -500dan menjalankannya dua kali, atau perubahan -200dan menjalankannya 5 kali.)

Ini juga akan gagal menangani nama file yang menyertakan spasi; sebagai @ rld ini jawaban menunjukkan, Anda dapat menggunakan find's -print0argumen, -zargumen untuk sortdan head, dan -0dengan xargsuntuk memastikan penanganan nama file yang tepat.

Akhirnya, jika tmp-dirsudah ada, Anda harus mengganti nama direktori yang tidak ada.

pemurah
sumber
Ini akan gagal jika ada nama file yang terdaftar dengan findmenyertakan spasi.
rld.
0

Untuk pengguna mac, skrip berikut harus dilakukan.

find . -type f -print0 | tr '\0' '\n' | sort -R | tail -n +10000 | tr '\n' '\0' | xargs -0 rm

trakan memungkinkan sort dan tail untuk mengerjakan daftar dengan \nalih - alih \0.

Luca Di Liello
sumber
-2

Cara termudah adalah dengan rm -rf direktori, lalu jalankan kembali skrip pembuatan data sambil memastikan tidak berjalan terlalu lama.

Lars Poulsen
sumber
Bukan itu yang diminta OP. Mungkin melakukan itu tidak layak.