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.