Вопрос или проблема
Я пишу скрипт LRU, но после 20 часов работы над ним у меня возникла проблема с рекурсивным режимом, которую я не могу исправить.
Мне просто нужна команда, которая покажет файлы, отсортированные по времени доступа (–time=atime); я также хочу управлять глубиной, но если не получится, тоже нормально.
- Основной каталог :
- Файл 1
- Каталог 1 :
- Файл 1
- Файл 2
- Подкаталог 1 :
- файл 1
- файл 2
- Каталог 2 :
- Файл 1
- Файл 2
- Подкаталог 2 :
- файл 1
- файл 2
- подкаталог 3 :
- файл 1
Я хочу исключить каталоги, оставив только файлы, отсортированные по времени доступа
например
/Основной каталог/Каталог 1/файл 1
/Основной каталог/Файл 1
/Основной каталог/Каталог 1/Подкаталог 1/файл 2
/Основной каталог/Каталог 2/Подкаталог 2/подкаталог 3/файл 1
и т.д..
Существует шесть очень популярных инструментов для решения подобных задач:
-
find
для поиска файлов или каталогов, соответствующих определенным записям.Опции
-mindepth
и-maxdepth
контролируют, насколько глубоко в дерево файловой системы (относительно заданных имен, которые всегда находятся на глубине 0) будет работать команда.Опция
-type
полезна для ограничения рассмотрения только файлами, каталогами, символическими ссылками или устройствами.Опция
-printf
крайне полезна, так как она заставляет команду выводить информацию о соответствующих именах (каталогах) в нужном формате. Мне особенно нравится%TY%Tm%Td %TT %p\n
, которая выводит дату и время последнего изменения, полный путь и имя каждого совпадения в каждой строке, используя форматYYYYMMDD HH:MM:SS.sss PATH
. Этот формат сортируется корректно, видите ли. Для последнего доступа используйте%AY%Am%Ad %AT %p\n
, но имейте в виду, что метки времени доступа вообще не записываются, если используется опция монтированияnoatime
, или если используется опция монтированияrelatime
, метки времени доступа изменяются только для первого доступа после изменения; проверка по принципу «наименее недавно использованных» в этом случае, таким образом, не надежна. (Список «наименее недавно измененных», однако, довольно надежен; пользователи могут изменять метки времени вручную, но в противном случае они поддерживаются автоматически.) -
sort
для сортировки вывода.Опции
-d
,-g
,-h
,-M
и-n
определяют, как сравниваются элементы, а опция-R
делает порядок случайным.Опция
-r
может использоваться для реверса порядка сортировки (используется в дополнение к одной из вышеперечисленных опций).Опция
-t
переопределяет, как определяются поля (столбцы); по умолчанию пробелы (пробелы и табуляции) разделяют столбцы.Опцию
-k
можно использовать для определения, какая часть каждой строки считается ключом сортировки; по умолчанию учитывается вся строка. -
uniq
часто используется после сортировки для объединения нескольких последовательных элементов в один — так, чтобы выводились только уникальные строки. -
cut
— самый простой способ выбрать только определенные столбцы из каждой строки в выводе.Опция
-f
выбирает поля для печати. (По умолчанию выводятся строки с максимум одним полем (без разделителей); опция-s
подавляет вывод таких строк.)Опция
-d
может использоваться для переопределения определения поля; по умолчанию пробелы разделяют поля. -
sed
— мощный потоковый редактор, который применяет регулярные выражения к входным данным, фильтруя и изменяя их по мере необходимости. -
awk
— интерпретатор языка awk. Скрипты awk по сути представляют собой набор действий, фрагментов кода, которые выполняются для каждой строки (или перед или после всей обработки, или если строка (или запись) соответствует какому-либо правилу).
Эту конкретную задачу можно решить с помощью трех из вышеупомянутых команд в простом конвейере: используйте find
, чтобы найти файлы на нужных глубинах дерева, выводя сортируемую дату и время для каждого файла, плюс относительный путь к файлу; отсортируйте вывод; уберите часть даты и времени из каждой строки, оставив только относительный путь к каждому файлу в каждой строке.
Самый простой способ — использовать zsh. Его глобальные квалификаторы могут сопоставлять и сортировать файлы на основе их типа, временных меток и других свойств.
print -lr -- *(.Doa)
print -lr -- **/*(.Doa)
Первая команда выводит имена обычных файлов (.
) в текущем каталоге, включая скрытые файлы (D
), отсортированные по времени доступа (oa
). Вторая команда выводит файлы в текущем каталоге и в его подкаталогах рекурсивно.
Я нахожу
$ find . -type f -printf '%AY%Am%Ad %AT %p\n'| sort |less
хорошей отправной точкой.
Ответ или решение
Для решения вашей задачи по рекурсивному поиску файлов, отсортированных по времени последнего доступа, мы можем использовать утилиту find
вместе с sort
. Это поможет вам получить список файлов, исключая директории, и отсортированных по времени доступа. Вот подробное объяснение, как это сделать.
Шаги по выполнению задачи
-
Использование команды
find
:
Командаfind
позволяет искать файлы и директории по заданным критериям. Мы будем использовать следующие опции:.
— для поиска в текущем каталоге и подкаталогах.-type f
— чтобы выбрать только файлы (исключая директории).-printf
— чтобы вывести нужные параметры файлов, включая время доступа.
-
Сортировка результатов:
Утилитаsort
будет использоваться для сортировки доступа по времени.
Команда
Вот возможная команда для решения вашей задачи:
find . -type f -printf '%AY-%Am-%Ad %AT %p\n' | sort | awk '{ $1=""; $2=""; print substr($0, 3) }'
Объяснение команды:
find . -type f
— ищет файлы в текущем каталоге и во всех подкаталогах.-printf '%AY-%Am-%Ad %AT %p\n'
— выводит дату и время последнего доступа и полный путь к файлу:%AY-%Am-%Ad
— год, месяц, день последнего доступа.%AT
— время последнего доступа.%p
— полный путь к файлу.
| sort
— сортирует вывод по времени доступа.| awk '{ $1=""; $2=""; print substr($0, 3) }'
— используется для удаления первых двух полей (даты и времени), оставляя только путь к файлу.substr($0, 3)
убирает лишние пробелы перед путем.
Примечание о глубине поиска
Ваша задача не требует управления глубиной, но если вы хотите ограничить глубину поиска, вы можете использовать флаги -maxdepth
и -mindepth
:
find . -maxdepth 2 -type f -printf '%AY-%Am-%Ad %AT %p\n' | sort | awk '{ $1=""; $2=""; print substr($0, 3) }'
-maxdepth 2
— ограничивает поиск только до вторых уровней вложенности от текущего каталога. Если вы хотите до конкретной глубины, просто измените число.
Заключение
Таким образом, используя комбинацию команд find
, sort
и awk
, вы можете получить массив файлов, отсортированных по времени доступа, согласно вашим требованиям. Это представленный подход является мощным инструментом для работы с файловыми системами в Linux и поможет вам в реализации вашего скрипта обработки LRU.