Здається, що 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
створюватимуть тимчасові файли (in /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
підтримка +
замість \;
? Тому що це робить те ж саме (передаючи декілька файлів як параметри), без -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
на більшу кількість
Я постійно використовую щось подібне, а також список топ-k останніх змінених файлів. Для великих дерев каталогів можна набагато швидше уникнути сортування . Що стосується лише топ-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.5x проти рішення 25.5s за допомогою сортування.
lastfile
), а потім можете робити все, що завгодно, з результатом, наприклад ls -l $(lastfile .)
, або open $(lastfile .)
(на Mac) тощо.
У Ubuntu 13 це робить наступне, можливо, швидше, оскільки він перевертає сортування і використовує "голову" замість "хвіст", зменшуючи роботу. Щоб показати 11 найновіших файлів у дереві:
знайти. -тип f -printf '% T @% p \ n' | сортувати -n -r | голова -11 | вирізати -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
}
І все-таки більшість робіт було виконано оригінальним рішенням плюндри. Дякую плюндру.
Я зіткнувся з тим же питанням. Мені потрібно знайти останній файл рекурсивно. на пошук знадобилося близько 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
Зважаючи на фіксовану тривалість стандартизованих дат у форматі 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
Цей простий кліп також буде працювати:
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>]
Usage2: відкриває останній змінений файл у редакторі
editlatest <log dir> [<glob match: default=*.log>]