Jak chcę to zrobić, jeśli chcę znaleźć najnowszy plik (mtime) w (dużym) katalogu zawierającym podkatalogi?
Wiele postów, które znalazłem, sugeruje pewne odmiany ls -lt | head
(zabawnie, wiele sugeruje, że ls -ltr | tail
jest to ta sama, ale mniej wydajna), co jest w porządku, chyba że masz podkatalogi (ja tak).
Z drugiej strony możesz
find . -type f -exec ls -lt \{\} \+ | head
co z pewnością sprawdzi się w przypadku tylu plików, ile może określić jedno polecenie, tzn. jeśli masz duży katalog, -exec...\+
wydasz osobne polecenia; dlatego każda grupa zostanie posortowana według ls
siebie, ale nie według całego zestawu; dlatego głowa wybierze ostatni wpis z pierwszej partii.
Jakieś odpowiedzi?
command-line
find
Bogaty
źródło
źródło
find: missing argument to '-exec'
+
nie ma on znaczeniabash
, więc nie ma potrzeby ucieczki.Odpowiedzi:
Nie musisz powracać do poleceń zewnętrznych (as
ls
), ponieważfind
możesz zrobić wszystko, czego potrzebujesz, poprzez-printf
akcję:źródło
find . -type f -exec stat --format=%y \{\} \+ | sort -r | head -n1
ale twoje rozwiązanie jest o wiele czystsze!| cut -d ' ' -f2
aby uzyskać tylko nazwę plikuhead
aby uwzględnić określoną liczbę wierszy. Potrzebowałem tylko pierwszej linii, więc użyłemhead -n 1
Miałem dzisiaj podobny problem, ale zaatakowałem go bez
find
. Potrzebowałem czegoś krótkiego, co mogłem uruchomić,ssh
aby zwrócić ostatnio edytowany plik w moim katalogu domowym. Z grubsza to wymyśliłem:-p
Opcjals
dodaje końcowy ukośnik do katalogów, gdygrep -v
linie Usuwa kończące się ukośnik (aka wszystkie katalogi), orazhead -1
ogranicza wyjście do jednego pliku.Jest to znacznie mniej szczegółowe niż używanie,
find
jeśli wszystko, co chcesz zwrócić, to nazwa pliku.źródło
Jest to w moim systemie szybciej niż
printf
, choć nie rozumiem dlaczegoźródło
... | sort -r | head -n1 | cut -d " " -f 4-
jeśli chcesz uzyskać tylko nazwę pliku.sort -r
będzie źle, jeśli nazwa pliku w wielu wierszach istnieje.EDYCJA: Myślę, że ten post nie jest „szczególnie przydatny”, tak jak myślałem. To naprawdę szybkie rozwiązanie, które śledzi ostatnio zmodyfikowany plik (zamiast sortować całą listę plików):
find . -type f -printf '%T@ %p\n' | awk 'BEGIN { mostrecenttime = 0; mostrecentline = "nothing"; } { if ($1 > mostrecenttime) { mostrecenttime = $1; mostrecentline = $0; } } END { print mostrecentline; }' | cut -f2- -d ' '
Rozłożony na wiele linii dla przejrzystości wygląda następująco:
Koniec edycji
Niezbyt przydatny post, ale ponieważ „aranżacja” dotyczyła szybkości, pomyślałem, że się tym podzielę.
Rozwiązania arrange i enzotib obejmują wylistowanie wszystkich plików w katalogu wraz z ich mtimes, a następnie sortowanie. Jak wiadomo sortowanie nie jest konieczne, aby znaleźć maksimum. Znalezienie maksimum można wykonać w czasie liniowym, ale sortowanie zajmuje n log (n) czasu [Wiem, że różnica nie jest duża, ale nadal;)]. Nie mogę wymyślić dobrego sposobu na wdrożenie tego. [EDYCJA: Schludna (choć brudna) i szybka implementacja podana powyżej.]
Następna najlepsza rzecz - aby znaleźć ostatnio edytowany plik w katalogu, rekurencyjnie znajdź ostatnio edytowany plik w każdym podkatalogu poziomu 1. Niech ten plik reprezentuje podkatalog. Teraz posortuj pliki poziomu 1 wraz z przedstawicielami podkatalogów poziomu 1. Jeśli liczba plików poziomu 1 i podkatalogów każdego katalogu jest prawie stała, proces ten powinien być skalowany liniowo z całkowitą liczbą plików.
Oto, co wymyśliłem, aby to wdrożyć:
Uruchomiłem to i dostałem mnóstwo
find: findrecent: No such file or directory
błędów. Powód: -exec find działa w innej powłoce. Próbowałem zdefiniować findrecent w .bashrc, .xsessionrc, ale to nie pomogło [doceniłbym tutaj pomoc]. W końcu zdecydowałem się na wprowadzeniew skrypcie wywoływanym
findrecent
w mojej ŚCIEŻCE, a następnie uruchamianym.Uruchomiłem to, czekałem i czekałem bez wyjścia. Dla pewności nie miałem do czynienia z żadnymi nieskończonymi pętlami, do których zmodyfikowałem plik
i spróbowałem jeszcze raz. To działało - ale zajęło mi 1 minutę 35 sekund na moim folderze domowym - rozwiązania arrange i enzotib zajęły odpowiednio 1,69, 1,95 sekundy!
Tyle o wyższości O (n) nad O (n log (n))! Cholera, zadzwoń narzut! [A raczej narzut wywołania skryptu]
Ale ten skrypt skaluje się lepiej niż wcześniejsze rozwiązania i założę się, że będzie działał szybciej niż one w banku pamięci google; D
źródło
Stosuj
perl
w połączeniu zfind
:Otrzymasz nazwę pliku z największą epoką == ostatni zmodyfikowany plik.
źródło
Nie jest to tak modne, ale można to również osiągnąć dzięki Midnight Commander : wyszukaj *, uporządkuj wynik, sortuj według czasu modyfikacji w odwrotnej kolejności.
Oczywiście jest to nieco wolniejsze niż
find
- mój katalog domowy, zawierający 922000 plików, został posortowanymc
w ciągu prawie 14 minut, podczas gdyfind
spędził mniej niż 5 - ale są pewne zalety:Prawdopodobnie spędziłbym dłużej niż różnicę 9 minut wymyślając odpowiednie wywołanie find :)
mniejsza szansa na błąd (zapomniałem podać -r do sortowania itp. - zacznij od nowa)
można grać z zestawem wyników, zmieniając kolejność sortowania itp. - bez ponownego zapytania plików.
możliwe jest wykonywanie operacji na plikach tylko na niektórych plikach z zestawu wyników - tj. sortuj według rozmiaru, usuń kilka dużych plików, które nie są potrzebne
źródło