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?

Dalibor Karlovic
sumber

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"'
Peter John Acklam
sumber
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)
jftuga
sumber
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.

AndreasM
sumber
"(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

Sirex
sumber
2

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

Khaled
sumber
0

mengapa tidak menggunakan kode sederhana ini:

$ ls -t1 foo/| xargs -d '\n' rm --
eppesuig
sumber
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