Szukam powłoki jednowierszowej, aby znaleźć najstarszy plik w drzewie katalogów.
72
Działa to (zaktualizowano w celu uwzględnienia sugestii Daniela Anderssona):
find -type f -printf '%T+ %p\n' | sort | head -n 1
find -type f -printf '%T+ %p\n' | sort | head -1
find
jest pusta z powodu faktu, że nazwa pliku zawiera nowy wiersz.Ten jest trochę bardziej przenośny i ponieważ nie opiera się na
find
rozszerzeniu GNU-printf
, więc działa również na BSD / OS X:Jedynym minusem jest to, że jest on nieco ograniczony do wielkości
ARG_MAX
(co powinno być nieistotne w przypadku większości nowszych jąder). Więc jeśligetconf ARG_MAX
zwrócono więcej niż znaki (262 144 w moim systemie), nie daje to poprawnego wyniku. Nie jest również zgodny z POSIX, ponieważ-print0
ixargs -0
nie jest.Poniżej przedstawiono kilka rozwiązań tego problemu: Jak znaleźć najnowszy (najnowszy, najwcześniejszy, najstarszy) plik w katalogu? - Wiki Grega
źródło
xargs: ls: terminated by signal 13
błąd jako efekt uboczny. Zgaduję, że to SIGPIPE. Nie mam pojęcia, dlaczego nie pojawia się podobny błąd, gdy przesyłam dane wyjściowe sortowania do głowicy w swoim rozwiązaniu.head
myślę , że to polecenie, które kończy pracę, gdy przeczyta linię, a tym samym „łamie” potok, tak myślę. Błądsort
nie pojawia się, ponieważ wydaje się, że nie narzeka, alels
w innym przypadku.xargs
trzeba wywołaćls
więcej niż jeden raz. W takim przypadku posortowane dane wyjściowe tych wielokrotnych wywołań kończą się konkatenacją, kiedy należy je połączyć.ls
go i gałki ocznej najstarszy plik rozwiązanie prawdopodobnie zostanie przekroczony limit długości wiersza poleceń, powodującls
powoływać się wielokrotnie. Otrzymasz złą odpowiedź, ale nigdy się nie dowiesz.Następujące polecenia polecenia gwarantują działanie z dowolnymi dziwnymi nazwami plików:
Użycie pustego bajtu (
\0
) zamiast znaku wysuwu wiersza (\n
) zapewnia, że wyjście find będzie nadal zrozumiałe, jeśli jedna z nazw plików zawiera znak wysuwu wiersza.-z
Przełącznik umożliwia zarówno rodzaj i grep interpretować jedynie jako zerowe bajty wycofanych z linii znaków. Ponieważ nie ma takiego przełącznika na głowę, używamygrep -m 1
zamiast tego (tylko jedno wystąpienie).Polecenia są uporządkowane według czasu wykonania (mierzonego na moim komputerze).
Pierwsze polecenie będzie najwolniejsze, ponieważ najpierw musi przekonwertować mtime każdego pliku na format czytelny dla człowieka, a następnie posortować te ciągi. Rurociągowanie do kota zapobiega zabarwieniu produktu wyjściowego.
Drugie polecenie jest nieco szybsze. Chociaż nadal wykonuje konwersję daty, sortowanie numeryczne (
sort -n
) sekund, które upłynęły od epoki Uniksa, jest nieco szybsze. sed usuwa sekundy od epoki Uniksa.Ostatnie polecenie w ogóle nie powoduje konwersji i powinno być znacznie szybsze niż pierwsze dwa. Sama komenda find nie wyświetla czasu mtime najstarszego pliku, więc statystyki są potrzebne.
Powiązane strony man: find - grep - sed - sort - stat
źródło
Chociaż zaakceptowana odpowiedź i inni tutaj wykonują zadanie, jeśli masz bardzo duże drzewo, wszystkie posortują całą wiązkę plików.
Lepiej byłoby, gdybyśmy mogli je po prostu wymienić i śledzić najstarsze, bez konieczności sortowania.
Właśnie dlatego wymyśliłem to alternatywne rozwiązanie:
Mam nadzieję, że może być pomocna, nawet jeśli pytanie jest nieco stare.
Edycja 1: zmiany te umożliwiają parsowanie plików i katalogów ze spacjami. Jest wystarczająco szybki, aby wydać go w katalogu głównym
/
i znaleźć najstarszy plik w historii.Wyjaśnienie polecenia:
Uruchamianie:
EDIT 2: Ta sama koncepcja, lepszym rozwiązaniem przy użyciu
find
patrzeć na czas dostępu (używać%T
od pierwszegoprintf
do czasu modyfikacji lub%C
o zmianie stanu zamiast).EDYCJA 3: Poniższa komenda wykorzystuje czas modyfikacji, a także drukuje przyrostowy postęp, ponieważ wyszukuje coraz starsze pliki, co jest przydatne, gdy masz niepoprawne znaczniki czasu (np. 1970-01-01):
źródło
ls
jest złe w skryptach, ponieważ jego dane wyjściowe nie są przeznaczone dla komputerów, formatowanie danych wyjściowych różni się w zależności od implementacji. Jak już wspomniano,find
jest dobry do pisania skryptów, ale może być również dobre dodanie tej informacji przed poinformowaniem ols
rozwiązaniach.Użyj ls - strona podręcznika informuje, jak zamówić katalog.
-N 2 jest tak, że nie otrzymujesz „sumy” na wyjściu. Jeśli chcesz tylko nazwę pliku.
A jeśli potrzebujesz listy w normalnej kolejności (uzyskanie najnowszego pliku)
Znacznie łatwiejsze niż użycie find, znacznie szybsze i bardziej niezawodne - nie musisz się martwić formatami nazewnictwa plików. Powinien również działać na prawie wszystkich systemach.
źródło
źródło
sort -n
.Wydaje się, że przez „najstarsze” większość ludzi przyjęło, że chodziło o „najstarszy czas modyfikacji”. Prawdopodobnie jest to poprawione, zgodnie z najbardziej rygorystyczną interpretacją „najstarszego”, ale w przypadku, gdybyś chciał tego z najstarszym czasem dostępu , zmodyfikowałbym najlepszą odpowiedź w ten sposób:
Zwróć uwagę na
%A+
.źródło
find ./search/dirname -type f -printf '%T+ %h/%f\n'
drukuje daty i nazwy plików w dwóch kolumnach.sort | head -n1
zachowuje linię odpowiadającą najstarszemu plikowi.echo $2
wyświetla drugą kolumnę, tj. nazwę pliku.źródło