it-swarm.com.ru

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

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

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

128
ack
ls -Art | tail -n 1

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

197
dmckee
ls -t | head -n1

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

107
chaos

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

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

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

52
gioele

Я использую:

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

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

9
user1195354

ls -lAtr | tail -1

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

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

ls -latr | tail -1

7
Jared Oberhaus

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

ls -t | head -1
5
Dmytro G. Sergiienko

Решение поиска/сортировки прекрасно работает до тех пор, пока количество файлов не станет действительно большим (как целая файловая система). Вместо этого используйте 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]* //'
3
Patrick

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

3
MikeB

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

Поскольку символ перевода строки является таким же допустимым, как и любой в имени файла, любое решение, основанное на строках , например, на основе 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, если вы также хотите рассмотреть скрытые файлы).

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

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

readarray -t -d '' < <(
  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 '' < <(
  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

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

3
Stephane Chazelas

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

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

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

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

(Запомните пространство между двумя знаками «<»!)

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

Я надеюсь, что это может помочь.

2
TrueY

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

ls -ltq  <path>  | head -n 1

Если вам нужно имя файла - последнее изменение, путь = /ab/cd/*.log

Если вам нужно имя каталога - последнее изменение, путь =/ab/cd/* /

1
RICHA AGGARWAL

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

ls -arRtlh | tail -50
1
mebada
ls -t -1 | sed '1q'

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

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

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

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

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

ls -rt | tail -n 1

Иначе

ls -Art | tail -n 1
0
jasonleonhard

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

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

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

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, см. Человек найти:

%Ak    File's  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's last status change time in the format specified by k, which is the same as for %A.
%Tk    File's last modification time in the format specified by k, which is the same as for %A.

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

0
basic6
ls -Frt | grep "[^/]$" | tail -n 1
0
João Fonseca

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

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