Получить самый последний файл в каталоге в Linux

Ищет команду, которая вернет единственный самый последний файл в каталоге.

Не вижу предельного параметра для ls...

Ответ 1

ls -Art | tail -n 1

Не очень элегантный, но он работает.

Ответ 2

ls -t | head -n1

Эта команда фактически дает последний измененный файл в текущем рабочем каталоге.

Ответ 3

Это рекурсивная версия (т.е. находит последний обновленный файл в определенном каталоге или в любом из его подкаталогов)

find $DIR -type f -printf "%[email protected] %p\n" | sort -n | cut -d' ' -f 2- | tail -n 1

Изменить: используйте -f 2- вместо -f 2, как предложено Кевином

Ответ 4

Я использую:

ls -ABrt1 --group-directories-first | tail -n1

Он дает мне только имя файла, исключая папки.

Ответ 5

ls -lAtr | tail -1

Другие решения не включают файлы, начинающиеся с '.'.

Эта команда также включает '.' и '..', которые могут быть или не быть такими, какие вы хотите:

ls -lAtr | tail -1

Ответ 6

Примечание о надежности:

Поскольку символ новой строки является таким же допустимым, как и любой в имени файла, любое решение, основанное на строках, подобных основанным на head/tail, имеет недостатки.

В GNU ls другой вариант - использовать опцию --quoting-style=shell-Always и массив bash:

eval "files=($(ls -t --quoting-style=shell-always))"
((${#files[@]} > 0)) && printf '%s\n' "${files[0]}"

(добавьте -A в ls если вы также хотите рассмотреть скрытые файлы).

Если вы хотите ограничиться обычными файлами (не обращая внимания на каталоги, fifo, устройства, символические ссылки, сокеты...), вам нужно прибегнуть к GNU find.

С bash 4.4 или новее (для readarray -d) и GNU coreutils 8.25 или новее (для cut -z):

readarray -t -d '' files < <(
  LC_ALL=C find . -maxdepth 1 -type f ! -name '.*' -printf '%[email protected]/%f\0' |
  sort -rzn | cut -zd/ -f2)

((${#files[@]} > 0)) && printf '%s\n' "${files[0]}"

Или рекурсивно:

readarray -t -d '' files < <(
  LC_ALL=C find . -name . -o -name '.*' -prune -o -type f -printf '%[email protected]%p\0' |
  sort -rzn | cut -zd/ -f2-)

Лучше всего было бы использовать zsh и его глобальные квалификаторы вместо bash чтобы избежать всех этих хлопот:

Самый новый обычный файл в текущем каталоге:

printf '%s\n' *(.om[1])

В том числе скрытые:

printf '%s\n' *(D.om[1])

Второй новейший:

printf '%s\n' *(.om[2])

Проверьте возраст файла после разрешения символической ссылки:

printf '%s\n' *(-.om[1])

Рекурсивный:

printf '%s\n' **/*(.om[1])

Кроме того, с compinit системой завершения (compinit и co), Ctrl+X m становится завершителем, который расширяется до самого нового файла.

Так:

vi Ctrl+Xm

Заставит вас отредактировать новейший файл (у вас также будет возможность увидеть, какой именно файл, прежде чем нажать Return).

vi Alt+2Ctrl+Xm

Для второго новейшего файла.

vi *.cCtrl+Xm

для новейшего файла c.

vi *(.)Ctrl+Xm

для самого нового обычного файла (не каталога, не fifo/device...) и т.д.

Ответ 7

Короткий вариант, основанный на ответе dmckee:

ls -t | head -1

Ответ 8

Решение поиска/сортировки отлично работает до тех пор, пока количество файлов не станет очень большим (как и вся файловая система). Используйте awk, чтобы просто отслеживать самый последний файл:

find $DIR -type f -printf "%[email protected] %p\n" | 
awk '
BEGIN { recent = 0; file = "" }
{
if ($1 > recent)
   {
   recent = $1;
   file = $0;
   }
}
END { print file; }' |
sed 's/^[0-9]*\.[0-9]* //'

Ответ 9

Мне нравится echo *(om[1]) (zsh синтаксис), так как это просто дает имя файла и не вызывает никакой другой команды.

Ответ 10

Я лично предпочитаю использовать как можно меньше встроенных команд bash (чтобы уменьшить количество дорогих fork и exec syscalls). Чтобы сортировать по дате, необходимо вызвать ls. Но использование head действительно не требуется. Я использую следующий однострочный (работает только в системах, поддерживающих каналы имен):

read newest < <(ls -t *.log)

или получить имя самого старого файла

read oldest < <(ls -rt *.log)

(Запомните пробел между двумя символами "<"!)

Если нужны скрытые файлы -A arg может быть добавлен.

Надеюсь, это поможет.

Ответ 11

используя рекурсивную опцию R.. вы можете рассмотреть это как улучшение для хороших ответов здесь

ls -arRtlh | tail -50

Ответ 12

попробуйте эту простую команду

ls -ltq  <path>  | head -n 1

Если вы хотите, чтобы имя файла - последнее изменение, path =/ab/cd/*. log

Если вы хотите, чтобы имя каталога - последнее изменение, path =/ab/cd/*/

Ответ 13

ls -t -1 | sed '1q'

Покажет последний измененный элемент в папке. Пара с grep, чтобы найти последние записи с ключевыми словами

ls -t -1 | grep foo | sed '1q'

Ответ 14

Рекурсивный:

find $1 -type f -exec stat --format '%Y :%y %n' "{}" \; | sort -nr | cut -d: -f2- | head

Ответ 15

Все эти решения ls/tail отлично работают для файлов в каталоге - игнорируют подкаталоги.

Чтобы включить все файлы в ваш поиск (рекурсивно), find можно использовать. gioele предложила сортировку форматированного вывода. Но будьте осторожны с пробелами (его предложение не работает с пробелами).

Это должно работать со всеми именами файлов:

find $DIR -type f -printf "%[email protected] %p\n" | sort -n | sed -r 's/^[0-9.]+\s+//' | tail -n 1 | xargs -I{} ls -l "{}"

Это похоже на mtime, см. man find:

%Ak    File  last  access  time in the format specified by k, which is either `@' or a directive for the C `strftime' function.  The possible values for k are listed below; some of them might not be available on all systems, due to differences in `strftime' between systems.
       @      seconds since Jan. 1, 1970, 00:00 GMT, with fractional part.
%Ck    File last status change time in the format specified by k, which is the same as for %A.
%Tk    File last modification time in the format specified by k, which is the same as for %A.

Так что просто замените %T на %C для сортировки по ctime.

Ответ 16

Поиск самого последнего файла в каждом каталоге в соответствии с шаблоном, например. вспомогательные каталоги рабочего каталога с именем, заканчивающимся на "tmp" (без учета регистра):

find . -iname \*tmp -type d -exec sh -c "ls -lArt {} | tail -n 1" \;

Ответ 17

Предполагая, что вам нет дела до скрытых файлов, которые начинаются с .

ls -rt | tail -n 1

Иначе

ls -Art | tail -n 1

Ответ 18

ls -Frt | grep "[^/]$" | tail -n 1

Ответ 19

Мне тоже нужно было это сделать, и я нашел эти команды. они работают для меня:

Если вы хотите получить последний файл по дате создания в папке (время доступа):

ls -Aru | tail -n 1  

И если вы хотите, чтобы последний файл имел изменения в его содержимом (изменить время):

ls -Art | tail -n 1