Кажется, что при ls
сортировке рекурсивных файлов файлы сортируются неправильно:
ls -altR . | head -n 3
Как найти последний измененный файл в каталоге (включая подкаталоги)?
Кажется, что при ls
сортировке рекурсивных файлов файлы сортируются неправильно:
ls -altR . | head -n 3
Как найти последний измененный файл в каталоге (включая подкаталоги)?
Ответы:
find . -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "
Для огромного дерева может быть трудно sort
сохранить все в памяти.
%T@
дает вам время модификации, как временная метка Unix, sort -n
численно сортирует, tail -1
берет последнюю строку (самая высокая временная метка), cut -f2 -d" "
обрезает первое поле (временную метку) из выходных данных.
Изменить: Точно так же, как -printf
, вероятно, только для GNU, использование ajreals stat -c
тоже. Хотя на BSD можно сделать то же самое, параметры форматирования разные (-f "%m %N"
казалось бы)
И я пропустил часть множественного числа; если вы хотите больше , то в последний файл, просто ударяться хвост аргумент.
sort -rn | head -3
вместо sort -n | tail -3
. Одна версия предоставляет файлы от самых старых до самых новых, а другая - от самых новых до самых старых.
sort
создаст временные файлы (в /tmp
) по мере необходимости, поэтому я не думаю, что это проблема.
-printf '%T@ %Tb %Td %TY %p\n'
даст вам штамп даты (при необходимости) (аналогично ls
)
find . -type f -printf '%TF %TT %p\n' | sort | tail -1
В ответ на ответ @ plundra , вот версия BSD и OS X:
find . -type f -print0 | xargs -0 stat -f "%m %N" |
sort -rn | head -1 | cut -f2- -d" "
find
Поддерживает ли BSD / OS X +
вместо \;
? Потому что это делает то же самое (передача нескольких файлов в качестве параметров), без -print0 | xargs -0
конвейера.
head -1
кhead -5
Вместо того, чтобы сортировать результаты и сохранять только последние измененные, вы можете использовать awk, чтобы напечатать только тот, который имеет наибольшее время модификации (во времени unix):
find . -type f -printf "%T@\0%p\0" | awk '
{
if ($0>max) {
max=$0;
getline mostrecent
} else
getline
}
END{print mostrecent}' RS='\0'
Это должно быть более быстрым способом решения вашей проблемы, если количество файлов достаточно велико.
Я использовал символ NUL (то есть '\ 0'), потому что, теоретически, имя файла может содержать любой символ (включая пробел и символ новой строки), кроме этого.
Если в вашей системе нет таких патологических имен файлов, вы также можете использовать символ новой строки:
find . -type f -printf "%T@\n%p\n" | awk '
{
if ($0>max) {
max=$0;
getline mostrecent
} else
getline
}
END{print mostrecent}' RS='\n'
Кроме того, это работает и в mawk.
mawk
, стандартная альтернатива Debian.
У меня была проблема, чтобы найти последний измененный файл под Solaris 10. Там find
нет printf
опции и stat
не доступен. Я обнаружил следующее решение, которое хорошо работает для меня:
find . -type f | sed 's/.*/"&"/' | xargs ls -E | awk '{ print $6," ",$7 }' | sort | tail -1
Чтобы показать имя файла, также используйте
find . -type f | sed 's/.*/"&"/' | xargs ls -E | awk '{ print $6," ",$7," ",$9 }' | sort | tail -1
объяснение
find . -type f
находит и перечисляет все файлыsed 's/.*/"&"/'
заключает путь в кавычки для обработки пробеловxargs ls -E
отправляет путь в кавычки ls
, -E
опция обеспечивает полную метку времени (формат год-месяц-день час-минута-секунды-наносекунды возврат )awk '{ print $6," ",$7 }'
извлекает только дату и времяawk '{ print $6," ",$7," ",$9 }'
извлекает дату, время и имя файлаsort
возвращает файлы, отсортированные по датеtail -1
возвращает только последний измененный файлКажется, это работает нормально, даже с подкаталогами:
find . -type f | xargs ls -ltr | tail -n 1
В случае, если слишком много файлов, уточните поиск.
-l
Вариант ls
кажется ненужным. Просто -tr
кажется достаточным.
find . -type f -print0 | xargs -0 ls -ltr | tail -n 1
Показывает последний файл с удобочитаемой отметкой времени:
find . -type f -printf '%TY-%Tm-%Td %TH:%TM: %Tz %p\n'| sort -n | tail -n1
Результат выглядит так:
2015-10-06 11:30: +0200 ./foo/bar.txt
Чтобы показать больше файлов, замените -n1
на большее число
Я постоянно использую что-то похожее, а также список самых последних измененных файлов. Для больших деревьев каталогов может быть намного быстрее избежать сортировки . В случае только топ-1 самого последнего измененного файла:
find . -type f -printf '%T@ %p\n' | perl -ne '@a=split(/\s+/, $_, 2); ($t,$f)=@a if $a[0]>$t; print $f if eof()'
В каталоге, содержащем 1,7 миллиона файлов, я получаю самый последний за 3.4 с, что в 7,5 раз быстрее, чем решение с 25,5 с использованием сортировки.
lastfile
), а затем вы можете делать с результатом все, что захотите, например ls -l $(lastfile .)
, или open $(lastfile .)
(на Mac) и т. Д.
В Ubuntu 13 следующее делает это, может быть, чуть быстрее, так как он меняет сортировку и использует «голову» вместо «хвоста», сокращая работу. Чтобы показать 11 новейших файлов в дереве:
найти . -тип f -printf '% T @% p \ n' | сортировать -n -r | голова -11 | cut -f2- -d "" | sed -e 's, ^. / ,,' | xargs ls -U -l
Это дает полный список ls без повторной сортировки и пропускает раздражающий «./», который «find» помещает в каждое имя файла.
Или, как функция bash:
treecent () {
local numl
if [[ 0 -eq $# ]] ; then
numl=11 # Or whatever default you want.
else
numl=$1
fi
find . -type f -printf '%T@ %p\n' | sort -n -r | head -${numl} | cut -f2- -d" " | sed -e 's,^\./,,' | xargs ls -U -l
}
Тем не менее, большая часть работы была сделана с помощью оригинального решения Plundra. Спасибо, Пундра.
Я столкнулся с той же проблемой. Мне нужно найти самый последний файл рекурсивно. поиск занял около 50 минут.
Вот небольшой скрипт, чтобы сделать это быстрее:
#!/bin/sh
CURRENT_DIR='.'
zob () {
FILE=$(ls -Art1 ${CURRENT_DIR} | tail -n 1)
if [ ! -f ${FILE} ]; then
CURRENT_DIR="${CURRENT_DIR}/${FILE}"
zob
fi
echo $FILE
exit
}
zob
Это рекурсивная функция, которая получает самый последний измененный элемент каталога. Если этот элемент является каталогом, функция вызывается рекурсивно и выполняет поиск в этом каталоге и т. Д.
Я считаю следующее короче и с более понятным выводом:
find . -type f -printf '%TF %TT %p\n' | sort | tail -1
Учитывая фиксированную длину стандартизованного формата datetime ISO, лексикографическая сортировка в порядке, и нам не нужна -n
опция для сортировки.
Если вы хотите снова удалить метки времени, вы можете использовать:
find . -type f -printf '%TFT%TT %p\n' | sort | tail -1 | cut -f2- -d' '
Если запуск stat
каждого файла по отдельности идет медленно, вы можете использовать его xargs
для ускорения:
find . -type f -print0 | xargs -0 stat -f "%m %N" | sort -n | tail -1 | cut -f2- -d" "
Это рекурсивно изменяет время изменения всех каталогов в текущем каталоге на самый новый файл в каждом каталоге:
for dir in */; do find $dir -type f -printf '%T@ "%p"\n' | sort -n | tail -1 | cut -f2- -d" " | xargs -I {} touch -r {} $dir; done
Этот простой cli также будет работать:
ls -1t | head -1
Вы можете изменить -1 на количество файлов, которые вы хотите перечислить
Мне показалась полезной приведенная выше команда, но в моем случае мне нужно было увидеть дату и время файла, а также возникла проблема с несколькими файлами, в именах которых есть пробелы. Вот мое рабочее решение.
find . -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" " | sed 's/.*/"&"/' | xargs ls -l
$ find . -type f -not -path '*/\.*' -printf '%TY.%Tm.%Td %THh%TM %Ta %p\n' |sort -nr |head -n 10
Хорошо обрабатывает пробелы в именах файлов - не то чтобы они использовались!
2017.01.25 18h23 Wed ./indenting/Shifting blocks visually.mht
2016.12.11 12h33 Sun ./tabs/Converting tabs to spaces.mht
2016.12.02 01h46 Fri ./advocacy/2016.Vim or Emacs - Which text editor do you prefer?.mht
2016.11.09 17h05 Wed ./Word count - Vim Tips Wiki.mht
Больше в find
изобилии по ссылке.
Для поиска файлов в / target_directory и всех его подкаталогах, которые были изменены за последние 60 минут:
$ find /target_directory -type f -mmin -60
Чтобы найти самые последние измененные файлы, отсортированные в обратном порядке времени обновления (т. Е. Сначала самые последние обновленные файлы):
$ find /etc -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort -r
Я предпочитаю этот, он короче
find . -type f -print0|xargs -0 ls -drt|tail -n 1
Я написал пакет pypi / github для этого вопроса, потому что мне также требовалось решение.
https://github.com/bucknerns/logtail
Установка:
pip install logtail
Использование: хвосты изменили файлы
logtail <log dir> [<glob match: default=*.log>]
Использование2: открывает последний измененный файл в редакторе
editlatest <log dir> [<glob match: default=*.log>]