Wygląda na to, że ls
nie sortuje plików poprawnie podczas wykonywania połączenia rekurencyjnego:
ls -altR . | head -n 3
Jak znaleźć ostatnio zmodyfikowany plik w katalogu (w tym w podkatalogach)?
Wygląda na to, że ls
nie sortuje plików poprawnie podczas wykonywania połączenia rekurencyjnego:
ls -altR . | head -n 3
Jak znaleźć ostatnio zmodyfikowany plik w katalogu (w tym w podkatalogach)?
Odpowiedzi:
find . -type f -printf '%T@ %p\n' | sort -n | tail -1 | cut -f2- -d" "
W przypadku wielkiego drzewa może być trudno sort
zachować wszystko w pamięci.
%T@
daje ci czas modyfikacji jak uniksowy znacznik czasu, sort -n
sortuje numerycznie, tail -1
pobiera ostatni wiersz (najwyższy znacznik czasu), cut -f2 -d" "
odcina pierwsze pole (znacznik czasu) od wyniku.
Edycja: Tak jak -printf
prawdopodobnie tylko GNU, tak samo użyteczne stat -c
jest użycie . Chociaż można zrobić to samo na BSD, opcje formatowania są inne ( -f "%m %N"
wydaje się)
I brakowało mi części liczby mnogiej; jeśli chcesz więcej niż ten ostatni plik, po prostu podbić argument ogon.
sort -rn | head -3
zamiast sort -n | tail -3
. Jedna wersja podaje pliki od najstarszego do najnowszego, a druga od najnowszej do najstarszej.
sort
utworzy pliki tymczasowe (w /tmp
) zgodnie z potrzebami, więc nie sądzę, że to niepokoi.
-printf '%T@ %Tb %Td %TY %p\n'
da ci datownik (w razie potrzeby) (podobny do ls
)
find . -type f -printf '%TF %TT %p\n' | sort | tail -1
W odpowiedzi na odpowiedź @ plundra , oto wersja BSD i OS X:
find . -type f -print0 | xargs -0 stat -f "%m %N" |
sort -rn | head -1 | cut -f2- -d" "
find
obsługuje +
zamiast tego \;
? Ponieważ robi to to samo (przekazując wiele plików jako parametry), bez -print0 | xargs -0
potoku.
head -1
sięhead -5
Zamiast sortować wyniki i przechowywać tylko te ostatnio zmodyfikowane, możesz użyć awk, aby wydrukować tylko ten z największym czasem modyfikacji (w czasie uniksowym):
find . -type f -printf "%T@\0%p\0" | awk '
{
if ($0>max) {
max=$0;
getline mostrecent
} else
getline
}
END{print mostrecent}' RS='\0'
Powinno to być szybszym sposobem rozwiązania problemu, jeśli liczba plików jest wystarczająco duża.
Użyłem znaku NUL (tj. „\ 0”), ponieważ teoretycznie nazwa pliku może zawierać dowolny znak (w tym spację i znak nowej linii), ale to.
Jeśli nie masz takich patologicznych nazw plików w systemie, możesz również użyć znaku nowej linii:
find . -type f -printf "%T@\n%p\n" | awk '
{
if ($0>max) {
max=$0;
getline mostrecent
} else
getline
}
END{print mostrecent}' RS='\n'
Ponadto działa to również w mawk.
mawk
standardową alternatywą Debiana.
Miałem problem ze znalezieniem ostatnio zmodyfikowanego pliku w systemie Solaris 10. Nie find
ma takiej printf
opcji i stat
nie jest dostępny. Odkryłem następujące rozwiązanie, które działa dobrze dla mnie:
find . -type f | sed 's/.*/"&"/' | xargs ls -E | awk '{ print $6," ",$7 }' | sort | tail -1
Aby wyświetlić również nazwę pliku, użyj
find . -type f | sed 's/.*/"&"/' | xargs ls -E | awk '{ print $6," ",$7," ",$9 }' | sort | tail -1
Wyjaśnienie
find . -type f
znajduje i wyświetla wszystkie plikised 's/.*/"&"/'
zawija nazwę ścieżki w cudzysłów, aby obsługiwać białe znakixargs ls -E
wysyła cytowaną ścieżkę do ls
, -E
opcja zapewnia zwrot pełnego znacznika czasu (format rok-miesiąc-dzień godzina-minuta-sekundy-nanosekundy )awk '{ print $6," ",$7 }'
wyodrębnia tylko datę i godzinęawk '{ print $6," ",$7," ",$9 }'
wyodrębnia datę, godzinę i nazwę plikusort
zwraca pliki posortowane według datytail -1
zwraca tylko ostatni zmodyfikowany plikTo wydaje się działać dobrze, nawet w podkatalogach:
find . -type f | xargs ls -ltr | tail -n 1
W przypadku zbyt wielu plików sprecyzuj wyszukiwanie.
-l
Opcja ls
wydaje się zbędne. Po prostu -tr
wydaje się wystarczająca.
find . -type f -print0 | xargs -0 ls -ltr | tail -n 1
Pokazuje najnowszy plik ze znacznikiem czasu czytelnym dla człowieka:
find . -type f -printf '%TY-%Tm-%Td %TH:%TM: %Tz %p\n'| sort -n | tail -n1
Wynik wygląda następująco:
2015-10-06 11:30: +0200 ./foo/bar.txt
Aby wyświetlić więcej plików, zamień -n1
na wyższy numer
Cały czas używam czegoś podobnego, a także listy najlepszych ostatnio modyfikowanych plików. W przypadku dużych drzew katalogów może być znacznie szybsze, aby uniknąć sortowania . W przypadku pierwszego najlepiej zmodyfikowanego pliku:
find . -type f -printf '%T@ %p\n' | perl -ne '@a=split(/\s+/, $_, 2); ($t,$f)=@a if $a[0]>$t; print $f if eof()'
W katalogu zawierającym 1,7 miliona plików otrzymuję najnowszy z 3,4 s, przyspieszenie 7,5x w stosunku do rozwiązania 25,5s za pomocą sortowania.
lastfile
), a następnie możesz robić, co chcesz z wynikiem, na przykład ls -l $(lastfile .)
, lub open $(lastfile .)
(na komputerze Mac) itp.
W Ubuntu 13 robi to, może odrobinę szybciej, ponieważ odwraca sortowanie i używa „głowy” zamiast „ogona”, co zmniejsza pracę. Aby wyświetlić 11 najnowszych plików w drzewie:
odnaleźć . -type f -printf '% T @% p \ n' | sort -n -r | głowa -11 | cut -f2- -d "" | sed -e 's, ^. / ,,' | xargs ls -U -l
Daje to pełną listę ls bez ponownego sortowania i pomija denerwujące „./”, które „find” umieszcza na każdej nazwie pliku.
Lub jako funkcja 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
}
Mimo to większość pracy została wykonana przy użyciu oryginalnego rozwiązania Plundry. Dzięki plundra.
Napotkałem ten sam problem. Muszę znaleźć najnowszy plik rekurencyjnie. znalezienie zajęło około 50 minut.
Oto mały skrypt, aby zrobić to szybciej:
#!/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
Jest to funkcja rekurencyjna, która pobiera najnowszą zmodyfikowaną pozycję katalogu. Jeśli ten element jest katalogiem, funkcja jest wywoływana rekurencyjnie i szuka w tym katalogu itp.
Uważam, że następujące wyniki są krótsze i bardziej zrozumiałe:
find . -type f -printf '%TF %TT %p\n' | sort | tail -1
Biorąc pod uwagę stałą długość znormalizowanych formatów danych ISO, sortowanie leksykograficzne jest w porządku i nie potrzebujemy -n
opcji sortowania.
Jeśli chcesz ponownie usunąć znaczniki czasu, możesz użyć:
find . -type f -printf '%TFT%TT %p\n' | sort | tail -1 | cut -f2- -d' '
Jeśli uruchamianie stat
każdego pliku osobno jest spowolnione, możesz użyć go xargs
do przyspieszenia:
find . -type f -print0 | xargs -0 stat -f "%m %N" | sort -n | tail -1 | cut -f2- -d" "
To rekurencyjnie zmienia czas modyfikacji wszystkich katalogów w bieżącym katalogu na najnowszy plik w każdym katalogu:
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
Ta prosta cli będzie również działać:
ls -1t | head -1
Możesz zmienić -1 na liczbę plików, które chcesz wyświetlić
Uznałem powyższe polecenie za przydatne, ale w moim przypadku musiałem zobaczyć datę i godzinę pliku, a także miałem problem z kilkoma plikami, które mają spacje w nazwach. Oto moje działające rozwiązanie.
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
Dobrze radzi sobie ze spacjami w nazwach plików - nie należy ich używać!
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
Więcej find
obfitości po linku.
Aby wyszukać pliki w katalogu / target_directory i wszystkich jego podkatalogach, które zostały zmodyfikowane w ciągu ostatnich 60 minut:
$ find /target_directory -type f -mmin -60
Aby znaleźć ostatnio zmodyfikowane pliki, posortowane w odwrotnej kolejności czasu aktualizacji (tj. Najpierw najnowsze zaktualizowane pliki):
$ find /etc -type f -printf '%TY-%Tm-%Td %TT %p\n' | sort -r
Wolę ten, jest krótszy:
find . -type f -print0|xargs -0 ls -drt|tail -n 1
Napisałem pypi / github na to pytanie, ponieważ potrzebowałem również rozwiązania.
https://github.com/bucknerns/logtail
Zainstalować:
pip install logtail
Zastosowanie: ogony zmieniły pliki
logtail <log dir> [<glob match: default=*.log>]
Użycie 2: Otwiera ostatnio zmieniony plik w edytorze
editlatest <log dir> [<glob match: default=*.log>]