Menghapus semuanya kecuali file terbaru


8

Katakanlah saya memiliki direktori ḟoo/yang berisi banyak file dalam semacam struktur direktori. Saya perlu menyimpan beberapa dari mereka, tetapi tidak semuanya.

Apakah ada cara untuk (di tempat) menghapus semuanya kecuali (katakanlah) 500 terbaru?

Jawaban:


11

Saya melakukan tugas ini secara teratur, dan saya menggunakan varian berikut ini. Ini adalah pipa yang menggabungkan berbagai alat sederhana: Temukan semua file, tambahkan waktu modifikasi file, sortir, hapus waktu modifikasi file, tampilkan semua baris kecuali 500 yang pertama, dan hapus:

find foo/ -type f | perl -wple 'printf "%12u ", (stat)[9]' | \
    sort -r | cut -c14- | tail -n +501 | \
    while read file; do rm -f -- "$file"; done

Beberapa komentar:

  • Jika Anda menggunakan "bash", Anda harus menggunakan "read -r file", bukan hanya "read file".

  • Menggunakan "perl" untuk menghapus file lebih cepat (dan juga menangani karakter "aneh" dalam nama file lebih baik daripada while-loop, kecuali jika Anda menggunakan "read -r file"):

    ... | tail -n +501 | perl -wnle 'unlink() or warn "$_: unlink failed: $!\n"'
    
  • Beberapa versi "tail" tidak mendukung opsi "-n", jadi Anda harus menggunakan "tail +501". Cara portabel untuk melewati 500 baris pertama adalah

     ... | perl -wnle 'print if $. > 500' | ...
    
  • Ini tidak akan berfungsi jika nama file Anda mengandung baris baru.

  • Itu tidak memerlukan GNU find.

Menggabungkan di atas memberi Anda:

find foo/ -type f | perl -wple 'printf "%12u ", (stat)[9]' | \
    sort -r | cut -c14- | perl -wnle 'print if $. > 500' | \
    perl -wnle 'unlink() or warn "$_: unlink failed: $!\n"'

Saya akan berhati-hati dengan itu rm -f.
— CVn

Bekerja seperti pesona! Ini harus tersedia sebagai alias dengan $ path dan params $ count. Terima kasih banyak!
— Dalibor Karlović

4

Ini adalah bagaimana saya akan melakukannya dengan Python 3. yang juga harus berfungsi untuk OS lain. Setelah menguji ini, pastikan untuk membatalkan komentar pada baris yang benar-benar menghapus file.

import os,os.path
from collections import defaultdict

FILES_TO_KEEP = 500
ROOT_PATH = r'/tmp/'

tree = defaultdict(list)

# create a dictionary containing file names with their date as the key
for root, dirs, files in os.walk(ROOT_PATH):
    for name in files:
        fname = os.path.join(root,name)
        fdate = os.path.getmtime( fname )
        tree[fdate].append(fname)

# sort this dictionary by date
# locate where the newer files (that you want to keep) end
count = 0
inorder = sorted(tree.keys(),reverse=True)
for key in inorder:
    count += len(tree[key])
    if count >= FILES_TO_KEEP:
        last_key = key
        break

# now you know where the newer files end, older files begin within the dict
# act accordingly
for key in inorder:
    if key < last_key:
        for f in tree[key]:
            print("remove ", f)
            # uncomment this next line to actually remove files
            #os.remove(f)
    else:
        for f in tree[key]:
            print("keep    ", f)

4

Saya tidak tahu tentang "500 terbaru", tetapi dengan menemukan Anda dapat menghapus hal-hal yang berumur lebih dari X menit / hari. Contoh untuk file dan lebih dari 2 hari:

find foo/ -mtime +2 -a -type f -exec rm -fv \{\} \;

Tes pertama dengan:

find foo/ -mtime +2 -a -type f -exec ls -al \{\} \;

Pikirkan garis miring terbalik dan ruang sebelum "\;". Lihat halaman manual find untuk info lebih lanjut.


"(Katakanlah) 500 terbaru" adalah esensi di sini, jadi saya tidak melihat bagaimana ini menjawab pertanyaan awal.
— Peter John Acklam

Maaf, tidak jelas bagi saya.
— AndreasM

3

jika Anda bisa melakukan dengan menjaga file x hari / jam bukan nomor x terbaru, Anda bisa melakukannya hanya dengan tmpwatch --ctime 7d


2

Saya pikir opsi -mtimedan perintah berguna untuk Anda. Anda dapat melihat untuk info lebih lanjut.-newerfindman find


0

mengapa tidak menggunakan kode sederhana ini:

$ ls -t1 foo/| xargs -d '\n' rm --

1
Bagaimana cara menghapus semua file kecuali 500 file terbaru? Dan bagaimana ini menangani subdirektori? Saya pikir Anda mungkin telah salah memahami postingan asli.
— Peter John Acklam
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.