Değiştirilen tarihe göre en son dosyayı bulun


38

En son dosyayı (mtime) alt dizinleri içeren (büyük) bir dizinde bulmak istersem, nasıl yaparım?

Bulduğum yayınların ls -lt | headçoğu ls -ltr | tail, alt dizinleriniz olmadıkça iyi olan (eğlenceli, pek çoğu aynı fakat daha az etkili olanı önerir) bir çeşitlilik gösteriyor .

Sonra tekrar yapabilirsin

find . -type f -exec ls -lt \{\} \+ | head

Bu, kesinlikle tek bir komutla belirtilebilecek sayıda dosya için hile yapacak, yani büyük bir dizine sahipseniz -exec...\+ayrı komutlar vereceğiz; bu nedenle her grup kendi içinde sıralanır lsancak toplam gruba göre değil; bu nedenle kafa, ilk partinin en son girişini alacak.

Cevap var mı?


BTW, bu ters eğik çizgilerin hiçbirine ihtiyacınız yok.
enzotib 13:11

@enzotib: yaparsınız ( \ + ), yoksa alırsınızfind: missing argument to '-exec'
düzenlenir

@ garip: Bu hatayı +hiçbir anlam ifade bashetmediğinden bu yüzden bu hatadan kaçmaya gerek yok.
enzotib 13:11

@enzotib: sen benim hatam, özür ediyoruz
düzenlemek

Yanıtlar:


46

Harici komutlara (as ls) tekrar findetmeniz gerekmez, çünkü -printfişlem sırasında ihtiyacınız olan her şeyi yapabilir :

find /path -printf '%T+ %p\n' | sort -r | head

1
Evet, geldim find . -type f -exec stat --format=%y \{\} \+ | sort -r | head -n1ama çözümün çok daha temiz!
Zengin

3
Ekleme | cut -d ' ' -f2dosya adını sadece almak için
qwr

Ayrıca, headbelirli sayıda satır eklemek için çıktısını toplayabilirsiniz . Sadece ilk satıra ihtiyacım vardı, o yüzden kullandımhead -n 1
Timmah

8

Bugün de benzer bir sorun yaşadım, ancak onsuz ona saldırdım find. Kısa Ben üzerinden çalıştırabilir şey gerekiyordu sshbenim ev dizininde En son düzenlenen dosyayı geri dönmek için. Kabaca bu ne buldum:

ls -tp | grep -v /$ | head -1

-pSeçenek lsdizinlere eğik çizgi ekler, grep -vbir çizgi (aka tüm dizinleri) ile biten kaldırır hatları ve head -1sınırları tek bir dosyaya çıktı.

Bu, findgeri dönmek istediğiniz tek şey dosya adıysa kullanmaktan çok daha az ayrıntılıdır .


Bu alt dizinleri işlemez.
Clément

4

Bu benim sistemimde olduğundan daha hızlı printf, ancak nedenini anlamıyorum

find /path -type f -exec stat -c "%y %n" {} + | sort -r | head

Onaylıyorum, daha hızlı.
enzotib 13:11

... | sort -r | head -n1 | cut -d " " -f 4-Sadece dosya ismini almak istiyorsanız bir nokta daha .
皞 皞

sort -rBirden fazla satırda dosya adı varsa, sadece yanlış olacağını öğrendim .
皞 皞

2

EDIT: Bu yazının düşündüğüm gibi 'özellikle kullanışlı değil' olduğunu düşünüyorum. Bu, en son değiştirilen dosyayı izleyen (tüm dosya listesini sıralamak yerine) gerçekten hızlı bir çözümdür:

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 ' '

Netlik için birden fazla satıra yayılmış olarak aşağıdaki gibi görünür:

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 ' '

EDIT’in sonu


Özellikle yararlı bir gönderi değil, ancak 'düzenlemek' hız tartışırken, bunu paylaşacağımı düşündüm.

arrange ve enzotib'in çözümleri dizindeki tüm dosyaları mtimları ile listelemeyi ve ardından sıralamayı içerir. Bildiğiniz gibi maksimum bulmak için sıralama gerekli değildir. Lineer zamanda maksimum bulma yapılabilir, ancak sıralama n log (n) zaman alır [aradaki fark çok fazla değil ama yine de;)]. Bunu yapmanın düzgün bir yolunu düşünemiyorum. [EDIT: Temiz (kirli görünümlü de olsa) ve yukarıda verilen hızlı uygulama.]

Sonraki en iyi şey - Bir dizindeki en son düzenlenen dosyayı bulmak için, her seviye 1 alt dizininde en son düzenlenen dosyayı tekrar tekrar bulun. Bu dosyanın alt dizini temsil etmesine izin verin. Şimdi seviye 1 dosyalarını, seviye 1 alt dizinlerinin temsilcileriyle birlikte sıralayın. Her dizinin seviye 1 dosyalarının ve alt dizinlerinin sayısı neredeyse sabitse, bu işlem toplam dosya sayısıyla doğrusal olarak ölçeklenmelidir.

Bunu uygulamak için geldiğim şey buydu:

findrecent() { { find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1; }
findrecent .

Bunu koştum ve bir sürü find: findrecent: No such file or directoryhata yaptım . Sebep: -exec farklı bir kabukta çalışır. Ben. Sonunda koymak için başvurdum

#!/bin/bash
{ find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1;

PATH'imde adı findrecentgeçen ve sonra çalıştıran bir komut dosyasında .

Bunu koştum, hiç beklemeden beklemeye devam ettim. Sadece sonsuz döngülerle ilgilenmediğimden emin olmak için dosyayı değiştirdim.

#!/bin/bash
echo "$1" >&2
{ find "$1" -maxdepth 1 -type f -exec stat -c "%y %n" {} + | sort -r | head -1 && find "$1" -mindepth 1 -maxdepth 1 -type d -exec findrecent {} \;; } | sort -r | head -1;

ve tekrar denedim. İşe yaradı - ancak ev klasörüme 1 dakika 35 saniye sürdü - aranjör ve enzotib'in çözümleri sırasıyla 1.69, 1.95 saniye sürdü!

O (n) 'in O (n log (n)) üzerindeki üstünlüğü için çok fazla! Kahretsin, seni çağır! [Veya komut dosyası çağrısı ek yükü]

Ancak bu komut dosyası önceki çözümlerden daha iyi ölçeklenir ve bahse girerim google’ın bellek bankasında olduğundan daha hızlı çalışacaktır;


2

perlConjonctin ile birlikte kullanın find:

 find my_directory -type f -printf '%T@\t%p\n' | perl -ane '@m=@F if ($F[0]>$m[0]); END{print $m[1];}'

En son epoch == değiştirilmiş son dosya olan dosyanın adını alırsınız.


1

Neredeyse moda değil, ancak Midnight Commander ile bunu başarmak da mümkün : * arayın, sonucu panelize edin, değişiklik zamanını tersine göre sıralayın.

Açıkçası, biraz daha yavaş find- 922000 dosyaları içeren ana dizim mcneredeyse 5 dakikadan findaz bir süre harcayarak 14 dakika içinde sıralandı - ancak bazı avantajlar var:

  • Muhtemelen daha uzun süre harcardım 9 dakika farkıyla uygun bir keşif çağrısı icat eder :)

  • hata şansı daha az (sıralama vb. için -r belirtmeyi unuttum - tekrar başla)

  • Sıralama sırasını değiştirerek sonuç setiyle oynamak mümkündür - dosyaları yeniden sorgulamaksızın.

  • Sonuç kümesinden sadece bazı dosyalar üzerinde dosya işlemleri yapmak mümkündür - yani boyuta göre sıralayın, gerekmeyen birkaç büyük dosyayı silin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.