Если я хочу найти самый последний файл (mtime) в (большом) каталоге, содержащем подкаталоги, как мне это сделать?
Множество постов, которые я нашел, предлагают некоторые варианты ls -lt | head
(забавно, многие предполагают, ls -ltr | tail
что это то же самое, но менее эффективно), что хорошо, если у вас нет подкаталогов (у меня есть).
Опять же, вы могли бы
find . -type f -exec ls -lt \{\} \+ | head
который определенно сделает то же самое для всех файлов, которые могут быть указаны одной командой, т. е. если у вас большой каталог, вы -exec...\+
будете запускать отдельные команды; поэтому каждая группа будет отсортирована ls
внутри себя, но не по общему набору; Таким образом, головка получит последнюю запись первой партии.
Есть ответы?
command-line
find
Богатый
источник
источник
find: missing argument to '-exec'
+
она не имеет смыслаbash
, поэтому не нужно ее избегать.Ответы:
Вам не нужно возвращаться к внешним командам (как
ls
), потомуfind
что вы можете делать все, что вам нужно, с помощью-printf
действия:источник
find . -type f -exec stat --format=%y \{\} \+ | sort -r | head -n1
но ваше решение намного чище!| cut -d ' ' -f2
чтобы получить только имя файлаhead
чтобы включить определенное количество строк. Мне нужна была только первая строка, поэтому я использовалhead -n 1
У меня была похожая проблема сегодня, но я атаковал ее без
find
. Мне нужно было что-то короткое, чтобы я мог перебратьssh
последний отредактированный файл в моем домашнем каталоге. Это примерно то, что я придумал:-p
Опцияls
добавляет слэш в каталогах, тоgrep -v
удаляет строки , оканчивающиеся на слэш (ака, все каталоги), иhead -1
ограничивает выход в один файл.Это гораздо менее многословно, чем использование,
find
если все, что вы хотите вернуть, это имя файла.источник
Это в моей системе быстрее, чем
printf
, хотя я не понимаю, почемуисточник
... | sort -r | head -n1 | cut -d " " -f 4-
если вы хотите получить только имя файла.sort -r
неправильным, если существует имя файла в нескольких строках.РЕДАКТИРОВАТЬ: я думаю, что этот пост не "не особенно полезен", как я думал, что это было. Это действительно быстрое решение, которое просто отслеживает последний измененный файл (вместо сортировки всего списка файлов):
find . -type f -printf '%T@ %p\n' | awk 'BEGIN { mostrecenttime = 0; mostrecentline = "nothing"; } { if ($1 > mostrecenttime) { mostrecenttime = $1; mostrecentline = $0; } } END { print mostrecentline; }' | cut -f2- -d ' '
Для ясности распределите его по нескольким строкам:
Конец РЕДАКТИРОВАНИЯ
Не очень полезный пост, но так как «аранжировка» обсуждала скорость, я решил поделиться этим.
Решения упорядочения и enzotib включают перечисление всех файлов в каталоге с их mtimes, а затем сортировку. Как известно, сортировка не нужна, чтобы найти максимум. Найти максимум можно за линейное время, но сортировка занимает n log (n) времени [я знаю, разница невелика, но все же;)]. Я не могу придумать изящный способ реализации этого. [РЕДАКТИРОВАТЬ: аккуратный (хотя грязный вид) и быстрая реализация, представленная выше.]
Следующая лучшая вещь - чтобы найти последний отредактированный файл в каталоге, рекурсивно найдите самый последний отредактированный файл в каждом подкаталоге уровня 1. Пусть этот файл представляет подкаталог. Теперь сортируйте файлы уровня 1 вместе с представителями подкаталогов уровня 1. Если количество файлов уровня 1 и подкаталогов в каждом каталоге почти постоянное, то этот процесс должен линейно масштабироваться с общим количеством файлов.
Вот что я придумал, чтобы реализовать это:
Я запустил это и получил кучу
find: findrecent: No such file or directory
ошибок. Причина: -exec команды find выполняется в другой оболочке. Я попытался определить findrecent в .bashrc, .xsessionrc, но это не помогло [я был бы признателен за помощь здесь]. В конце концов я прибегнул кв сценарии, вызванном
findrecent
в моем PATH, а затем запустить его.Я запустил это, продолжал ждать и ждать без выхода. Просто чтобы убедиться, что я не имел дело с бесконечными циклами, я изменил файл
и попробовал еще раз. Это сработало - но заняло 1 минуту 35 секунд в моей домашней папке - решения аранжировки и энзотиба заняли 1,69 и 1,95 секунды соответственно!
Вот вам и превосходство O (n) над O (n log (n))! Черт возьми, функция вызова накладных расходов! [Или скорее сценарий вызова накладных расходов]
Но этот скрипт масштабируется лучше, чем предыдущие решения, и я уверен, что он будет работать быстрее, чем они в банке памяти Google; D
источник
использование
perl
в сочетании сfind
:Вы получите имя файла с наибольшей эпохой == последний измененный файл.
источник
Это не так модно, но также возможно достичь этого с Midnight Commander : искать *, группировать результаты, сортировать по времени изменения в обратном порядке.
Очевидно, это немного медленнее, чем
find
- мой домашний каталог, содержащий 922000 файлов, был отсортированmc
почти за 14 минут, аfind
потрачено менее 5 - но есть некоторые преимущества:Вероятно, я бы потратил больше, чем разница в 9 минут, придумывая правильный вызов find :)
меньше шансов на ошибку (забыл указать -r для сортировки и т. д. - начать заново)
можно поиграть с результирующим набором, изменив порядок сортировки и т. д. - без повторного запроса файлов.
можно выполнять файловые операции только над некоторыми файлами из результирующего набора - т.е. сортировать по размеру, удалять несколько больших файлов, которые не нужны
источник