Найдите самый старый файл (рекурсивно) в каталоге

Существует инструмент под названием Dev Toolkit , он позволяет запускать приватный блокчейн, проводник блоков, клиент и т. Д.

10
задан tzot 8 May 2009 в 09:13
поделиться

7 ответов

Хм. Ответ Нади ближе к тому, что вы имели в виду , чтобы спросить; однако, чтобы найти (один) самый старый файл в дереве, попробуйте следующее:

import os
def oldest_file_in_tree(rootfolder, extension=".avi"):
    return min(
        (os.path.join(dirname, filename)
        for dirname, dirnames, filenames in os.walk(rootfolder)
        for filename in filenames
        if filename.endswith(extension)),
        key=lambda fn: os.stat(fn).st_mtime)

С небольшой модификацией вы можете получить n самых старых файлов (аналогично ответу Нади):

import os, heapq
def oldest_files_in_tree(rootfolder, count=1, extension=".avi"):
    return heapq.nsmallest(count,
        (os.path.join(dirname, filename)
        for dirname, dirnames, filenames in os.walk(rootfolder)
        for filename in filenames
        if filename.endswith(extension)),
        key=lambda fn: os.stat(fn).st_mtime)

Обратите внимание, что использование метода .endswith позволяет вызовам как:

oldest_files_in_tree("/home/user", 20, (".avi", ".mov"))

выбрать более одного расширения.

Наконец, если вам нужен полный список файлов, упорядоченный по времени модификации, чтобы удалить как можно больше при необходимости освободите место, вот код:

import os
def files_to_delete(rootfolder, extension=".avi"):
    return sorted(
        (os.path.join(dirname, filename)
         for dirname, dirnames, filenames in os.walk(rootfolder)
         for filename in filenames
         if filename.endswith(extension)),
        key=lambda fn: os.stat(fn).st_mtime),
        reverse=True)

и обратите внимание, что reverse = True выводит самые старые файлы в конец списка, так что для удаления следующего файла вы просто делаете file_list.pop () .

Кстати, для полного решения вашей проблемы, поскольку вы работаете в Linux, Если доступно os.statvfs , вы можете сделать:

import os
def free_space_up_to(free_bytes_required, rootfolder, extension=".avi"):
    file_list= files_to_delete(rootfolder, extension)
    while file_list:
        statv= os.statvfs(rootfolder)
        if statv.f_bfree*statv.f_bsize >= free_bytes_required:
            break
        os.remove(file_list.pop())

statvfs.f_bfree - это свободные блоки устройства, а statvfs.f_bsize - размер блока. Мы берем корневую папку statvfs, так что учтите любые символические ссылки, указывающие на другие устройства, где мы могли бы удалить много файлов, фактически не освобождая место на этом устройстве.

ОБНОВЛЕНИЕ (копирование комментария Хуаном):

В зависимости от ОС и реализации файловой системы, вы можете захотеть умножить f_bfree на f_frsize, а не на f_bsize. В некоторых реализациях последний является предпочтительным размером запроса ввода-вывода. Например, в системе FreeBSD 9, которую я только что протестировал, f_frsize было 4096, а f_bsize было 16384. POSIX говорит, что поля счетчиков блоков «в единицах f_frsize» (см. http://pubs.opengroup.org/onlinepubs/ 9699919799 // basedefs / sys_statvfs.h.

23
ответ дан 3 December 2019 в 13:18
поделиться

Чтобы сделать это в Python, вы можете использовать os.walk (путь) для рекурсивной итерации по файлам, а также st_size и st_mtime атрибутов os.stat (имя файла) для получения размеров файлов и времени их модификации.

13
ответ дан 3 December 2019 в 13:18
поделиться

Я думаю, что самый простой способ сделать это - использовать find вместе с ls -t (сортировать файлы по времени).

что-то в этом духе должно помочь (удаляет самый старый файл avi в указанном каталоге )

find / -name "*.avi" | xargs ls -t | tail -n 1 | xargs rm

шаг за шагом ....

find / -name "* .avi" - найти все avi файлы рекурсивно, начиная с корневого каталога

xargs ls -t - отсортировать все файлы, найденные по времени модификации, от самого нового до самого старого.

tail -n 1 - получить последний файл в списке (самый старый)

xargs rm - и удалить его

7
ответ дан 3 December 2019 в 13:18
поделиться

Вы можете использовать модули stat и fnmatch вместе, чтобы найти файлы

ST_MTIME, относящиеся ко времени последнего изменения. Вы можете выбрать другое значение, если хотите

import os, stat, fnmatch
file_list = []
for filename in os.listdir('.'):
    if fnmatch.fnmatch(filename, '*.avi'):
        file_list.append((os.stat(filename)[stat.ST_MTIME], filename))

. Затем вы можете упорядочить список по времени и удалить в соответствии с ним.

file_list.sort(key=lambda a: a[0])
10
ответ дан 3 December 2019 в 13:18
поделиться

Проверьте команду linux find .

В качестве альтернативы, этот пост направляет вместе ls и tail для удаления самого старого файла в каталоге. Это может быть сделано в цикле, когда не хватает свободного места.

Для справки, вот код оболочки, который это делает (перейдите по ссылке для получения дополнительной альтернативы и обсуждения):

ls -t -r -1 /path/to/files | head --lines 1 | xargs rm
2
ответ дан 3 December 2019 в 13:18
поделиться

Модуль os предоставляет функции, необходимые для получения списков каталогов и информации о файле в Python. Я обнаружил, что os.walk особенно полезен для рекурсивного хождения по каталогам, и os.stat предоставит вам подробную информацию (включая время модификации) по каждой записи.

Вы можете сделать это проще с простой командой оболочки. Будет ли это работать лучше для вас или нет, зависит от того, что вы хотите сделать с результатами.

0
ответ дан 3 December 2019 в 13:18
поделиться

Вот еще одна формулировка Python, которая немного устаревшая по сравнению с некоторыми другими, но ее легко изменить и обрабатывает случай отсутствия совпадающих файлов без создания исключения.

import os

def find_oldest_file(dirname="..", extension=".avi"):
    oldest_file, oldest_time = None, None
    for dirpath, dirs, files in os.walk(dirname):
        for filename in files:
            file_path = os.path.join(dirpath, filename)
            file_time = os.stat(file_path).st_mtime
                if file_path.endswith(extension) and (file_time<oldest_time or oldest_time is None):
                oldest_file, oldest_time = file_path, file_time
    return oldest_file, oldest_time

print find_oldest_file()
3
ответ дан 3 December 2019 в 13:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: