Unix / Linux değiştirilmiş tarihe göre bulur ve sıralar


138

findEn son değiştirilen sonuçları sıralayan basit bir işlemi nasıl yapabilirim ?

İşte findkullanıyorum akım (PHP'de bir kabuk kaçış yapıyorum, bu yüzden değişkenlerin nedeni budur):

find '$dir' -name '$str'\* -print | head -10

Bu siparişi en son değiştirilen arama sırasına göre nasıl alabilirim? (Not aramadan sonra 'sıralamak' istemiyorum, ancak sonuçları en son neyin değiştirildiğine bağlı olarak bulmak istemiyorum.)


github.com/shadkam/recentmost istenen ne yapacağını - ama bir inşa gerekiyor
user3392225

Yanıtlar:


153

Bunu kullan:

find . -printf "%T@ %Tc %p\n" | sort -n

printfargümanları man find:

  • %Tk: Dosyanın en son değişiklik zamanı, belirtilen formatta k.

  • @: 1 Ocak 1970, 00:00 GMT’den bu yana birkaç saniye.

  • c: yerel ayar tarihi ve saati (Kasım 04: 12:02:33 EST 1989).

  • %p: Dosyanın adı.


5
+1 Çok yararlı, bununla ilgili ilk yanıtı okunabilir / yararlı bir tarih çıktısı ile buldum
Jake N

En güvenilir (ve çok basit) zamanın sayısal olarak sıralı olması (bu nedenle her zaman uygun şekilde sıralanabilir), tx!
Kova Gücü

1
İçimdeki son dosyaları bulmak için bu diğer adı kullanıyorum ~/.zshrc: fr () { find ./ -iname "*"$@"*" -printf "%T@ %Td-%Tb-%TY %Tk:%TM %p\n" | sort -n | cut -d " " -f 2- | grep -i "$@" ; }Bu komut, ( fr <pattern>) komutuna iletilen ilk argüman modelini içeren tüm dosyaları tekrarlı olarak bulur ve en sonuncusuyla sıralar.
joelostblom

Bu harika !!! Simgeler ile kullanmak için find -L ...
Varun Chandak

1
Sen kullanmak isteyebilirsiniz ssedsaniye fraksiyonel parçası kurtulmak ve hala @PeterMortensen gösteriyordu ISO8601 kullanın:find . -type f -printf "%TY-%Tm-%TdT%TT %p\n" | sort -r | ssed -R 's/^([^.]+)\.\d+ (.*)$/\1 \2/'
Ludovic Kuty

83

Glob niteleyicileri sayesinde en kolay yöntem zsh kullanmaktır .

print -lr -- $dir/**/$str*(om[1,10])

Eğer GNU bulursanız, dosya değiştirme zamanlarını yazdırmasını ve buna göre sıralamasını sağlayın.

find -type f -printf '%T@ %p\0' |
sort -zk 1nr |
sed -z 's/^[^ ]* //' | tr '\0' '\n' | head -n 10

Eğer GNU’yu bulup diğer GNU uygulamalarını bulamadıysanız, yeni satırları boş satır yerine ayırıcı olarak kullanın; yeni satırlar içeren dosya adlarına olan desteği kaybedersiniz.

find -type f -printf '%T@ %p\n' |
sort -k 1nr |
sed 's/^[^ ]* //' | head -n 10

Eğer Perl varsa (burada dosya isimlerinde yeni satır olmadığını varsayacağım):

find . -type f -print |
perl -l -ne '
    $_{$_} = -M;  # store file age (mtime - now)
    END {
        $,="\n";
        @sorted = sort {$_{$a} <=> $_{$b}} keys %_;  # sort by increasing age
        print @sorted[0..9];
    }'

Python'unuz varsa (ayrıca dosya adlarında yeni satırlar olmadığını varsayarak):

find . -type f -print |
python -c 'import os, sys; times = {}
for f in sys.stdin.readlines(): f = f[0:-1]; times[f] = os.stat(f).st_mtime
for f in (sorted(times.iterkeys(), key=lambda f:times[f], reverse=True))[:10]: print f'

PHP'de aynı şeyi yapmanın muhtemelen bir yolu vardır, ama bilmiyorum.

Yalnızca POSIX araçlarıyla çalışmak istiyorsanız, daha karmaşıktır; Değişiklik tarihine göre sıralı olarak sıralanan dosyaların nasıl listeleneceğine bakınız (hiçbir stat komutu mevcut değil!) (ilk 10'u tekrar düzenlemek kolay kısımdır).


Bence findversiyon en eski dosyaları gösterir ve eklemek gerekir -rseçeneği sort.
Quentin Pradet

Sed, bir -z seçeneği olmadığını söylüyor.
Kef Schecter

@KefSchecter Daha sonra ayırıcı olarak yeni satırlar kullanın, ancak dosya adlarındaki yeni satırlar için desteği kaybedersiniz.
Gilles

Yukarıdakiler python2 içindir. Yalnızca python3 varsa, bazı küçük değişiklikler olur: python3 -c 'import os, sys; sys.stdin.readlines () içindeki f için times = {}: f = f [0: -1]; [f] = os.stat (f) .st_mtime f in (sıralı (times.keys (), key = lambda f: times [f], ters = Doğru)) [: 10]: print (f); '
Neil McGill

40

PHP ya da Python'a ihtiyacınız yok, sadece ls :

man ls:
-t     sort by modification time
-r,    reverse order while sorting (--reverse )
-1     list one file per line

find /wherever/your/files/hide -type f -exec ls -1rt "{}" +;

Eğer komut * başarısızlık durumundan çıkarsa (ör. Argüman listesi çok uzun ), bulma ile yineleyebilirsiniz. 'Den başka bir deyişle: Yeni bir işlem için maksimum argüman uzunluğu

  • find . -print0|xargs -0 command (Bulma işlemi "-exec +" uygulamıyorsa ancak "-print0" i biliyorsa, hızı en iyi duruma getirir)
  • find . -print|xargs command (bağımsız değişkenlerde boşluk yoksa)

Bağımsız değişkenlerin büyük bir kısmı uzun, mutlak veya göreceli yollardan oluşuyorsa, eylemlerinizi dizine taşımayı deneyin: cd /directory/with/long/path; command *Başka bir hızlı düzeltme daha az sayıda argümanla eşleşmek için olabilir:command [a-e]*; command [f-m]*; ...


1
Çok fazla dosya varsa, bu, ls'de 'Çok uzun değişken listesi' ile başarısız olur.
okulus

1
Bu doğru, ancak sorunun "basit bir
bulguyu

2
ls, dosya adlarının xargs'in anlayabileceği bir şekilde alıntı yapmaz (-0 seçeneği yoktur ve çeşitli alıntı stilleri yetersizdir)
Tobu,

10

Sadece ls'e ihtiyacınız var

find /wherever/your/files/hide -type f -exec ls -1rt "{}" +;Yukarıda belirtildiği gibi yapabilirsiniz

veya

ls -1rt `find /wherever/your/file/hides -type f`

2
Çok fazla dosya varsa, bu, ls'de 'Çok uzun değişken listesi' ile başarısız olur. Belki Xargs kullanmak için recook?
okulus

2
Ancak, birden çok kez xargsçağırırsa ls, sıralama bozulur.
Aaron D. Marasco

Bu, adlarında boşluk olan dosyalar için başarısız olur. Herhangi bir tavsiye?
user74094

Sadece bu cevaba rastladım ve tam da benzer bir durumda ihtiyacım olan şeydi. Soru: +;Sonunda ne yapar ? Bu olmadan aynı sonucu veriyor gibi görünüyor, ;ancak olmadan işe yaramazsa +?
RoketNuts

Bu, başka bir cevap kullanımı hakkında kısmı hariç 8 ay önce yayınlanan tıpkı aynıdır "bulmak` -1rt ls ... `" kırık olan
Clément

7

User195696 kullanıcısının yanıtını genişletme :

find . -type f -printf "%T@\t%Tc %6k KiB %p\n" | sort -n | cut -f 2-

Her dosya için, bu ilk çıkış (çizelge ardından göre sıralama için, sayısal zaman damgası \t), daha sonra, bir insan tarafından okunabilir bir zaman damgası, daha sonra dosya boyutu (ne yazık ki findsitesindeki -printfgöre sadece kibibayt, mebibytes yapamayacağı), daha sonra dosya yol, yörünge.

Sonra sort -nonu ilk sayısal alana göre sıralar.

Sonra cutkullanıcının ilgisini çekmeyen ilk sayısal alandan kurtulur. (İkinci alanı ileri doğru yazdırır.) Varsayılan alan ayırıcı \tveya tablolamadır.

Çıktı örneği:

Thu 06 Feb 2014 04:49:14 PM EST     64 KiB ./057_h2_f7_10/h2_f7_10.class
Fri 07 Feb 2014 02:08:30 AM EST 7962976 KiB ./056_h2_f7_400/h2__rh_4e-4.mph
Fri 07 Feb 2014 02:23:24 AM EST 7962976 KiB ./056_h2_f7_400/h2_f7_400_out_Model.mph
Fri 07 Feb 2014 02:23:24 AM EST      0 KiB ./056_h2_f7_400/h2_f7_400_out.mph.status
Fri 07 Feb 2014 02:23:24 AM EST     64 KiB ./056_h2_f7_400/1579678.out
Fri 07 Feb 2014 03:47:31 AM EST 8132224 KiB ./057_h2_f7_10/h2__rh_1e-5.mph
Fri 07 Feb 2014 04:00:49 AM EST 8132224 KiB ./057_h2_f7_10/h2_f7_10_out_Model.mph
Fri 07 Feb 2014 04:00:49 AM EST      0 KiB ./057_h2_f7_10/h2_f7_10_out.mph.status
Fri 07 Feb 2014 04:00:49 AM EST     64 KiB ./057_h2_f7_10/1579679.out
Fri 07 Feb 2014 09:47:18 AM EST   9280 KiB ./056_h2_f7_400/h2__rh_4e-4.mat
Fri 07 Feb 2014 10:51:23 AM EST   9728 KiB ./018_bidomain/h2_plain__rh_1e-5.mat
Fri 07 Feb 2014 10:58:33 AM EST   9568 KiB ./057_h2_f7_10/h2__rh_1e-5.mat
Fri 07 Feb 2014 05:05:38 PM EST     64 KiB ./058_h2_f7_stationary/h2_f7_stationary.java
Fri 07 Feb 2014 06:06:29 PM EST     32 KiB ./058_h2_f7_stationary/slurm.slurm
Sat 08 Feb 2014 03:42:07 AM EST      0 KiB ./058_h2_f7_stationary/1581061.err
Sat 08 Feb 2014 03:42:14 AM EST     64 KiB ./058_h2_f7_stationary/h2_f7_stationary.class
Sat 08 Feb 2014 03:58:28 AM EST  70016 KiB ./058_h2_f7_stationary/h2s__rh_1e-5.mph
Sat 08 Feb 2014 04:12:40 AM EST  70304 KiB ./058_h2_f7_stationary/h2s__rh_4e-4.mph
Sat 08 Feb 2014 04:12:53 AM EST  70304 KiB ./058_h2_f7_stationary/h2_f7_stationary_out_Model.mph
Sat 08 Feb 2014 04:12:53 AM EST      0 KiB ./058_h2_f7_stationary/h2_f7_stationary_out.mph.status
Sat 08 Feb 2014 04:12:53 AM EST     32 KiB ./058_h2_f7_stationary/1581061.out
Mon 10 Feb 2014 11:40:54 AM EST    224 KiB ./058_h2_f7_stationary/h2s__rh_4e-4.mat
Mon 10 Feb 2014 11:42:32 AM EST    224 KiB ./058_h2_f7_stationary/h2s__rh_1e-5.mat
Mon 10 Feb 2014 11:50:08 AM EST     32 KiB ./plot_grid.m

Dosya boyutu alanını 6 karakterden kasten oluşturdum, çünkü daha uzun hale getirirseniz, dosyaların ne kadar büyük olduğunu görsel olarak ayırt etmek zorlaşır. Bu şekilde, 1e6 KiB'den büyük dosyalar çıkarır: 1 karakter 1-9 GB, 2 karakter 10-99 GB vb.


Düzenleme: işte başka bir sürüm ( find . -printf "%Tc"MinGW / MSYS’de çöktüğü için):

find . -type f -printf "%T@\t%p\n" | sort -n | cut -f 2- | xargs -I{} ls -Glath --si {}

Gibi çıktı verilmesi:

-rw-r--r-- 1 es 23K Jul 10  2010 ./laptop_0000071.jpg
-rw-r--r-- 1 es 43M Jul 29 19:19 ./work.xcf
-rw-r--r-- 1 es 87K Jul 29 20:11 ./patent_lamps/US Patent 274427 Maxim Lamp Holder.jpg
-rw-r--r-- 1 es 151K Jul 29 20:12 ./patent_lamps/Edison screw-in socket.png
-rw-r--r-- 1 es 50K Jul 29 20:13 ./patent_lamps/1157 Lamp.jpg
-rw-r--r-- 1 es 38K Jul 29 20:14 ./patent_lamps/US06919684-20050719-D00001.png

Nerede:

  • -I{}oluşumunun {}bir argümanla değiştirilmesine neden olur ve yeni satırlar artık argüman ayırıcılarıdır (yukarıdaki dosya adlarındaki boşlukları not edin).

  • ls -G Grup adının yazdırılmasını önler (alan israfı)

  • ls -h --siinsan tarafından okunabilen dosya boyutları üretir (ile daha doğru --si).

  • ls -t zamanla sıralar, ki burada önemsiz, ama genelde kullandığım şey bu.


1
Not: bunun yerine dosya boyutuna göre sıralamak için , yukarıdaki komutlardan herhangi birindeki T@by skomutunu değiştirmeniz yeterlidir .
Evgeni Sergeev

3

@ User195696'nin yanıtının OS X varyantı:

  1. Zaman damgası ile:

    find . -type f -exec stat -f "%Sm %N" -t "%Y%y%m%d%H%M" {} \; | sort -r
    
  2. Zaman damgası olmadan:

    find . -type f -exec stat -f "%Sm %N" -t "%Y%y%m%d%H%M" {} \; | sort -r | awk -F' ' '{ print substr($0, length($1) + 2) }'
    

2

Bunun Mac OS X'te iş yapılacağını öğrendim (ve diğer Unixen'de çalışacak kadar genel):

find . -type f -ls | awk '{print $(NF-3), $(NF-2), $(NF-1), $NF}' | sort

2
Maalesef, bu, Hırvat ayarlarımdaki yerel ay adlarını yazdırarak sıralamada hata oluştu.
Ivan Vučica

user195696'nın cevabı Hırvat kurulumunda (ve diğerlerinde) çalışır.
Peter Mortensen

1

Senin Eğer findseçimi çok basittir, onsuz yapabilmek ve sadece kullanabilirsiniz ls:

ls -1 *.cc # -r -t optional

1

Deneyin:

find '$dir' -name '$str'\* -print | xargs ls -tl | head -10

Ancak verileri -mmin/ -mtimeve ' ye göre filtrelemek de yararlıdır -type.


1

kullanın:

find . -type f -mtime 0 -printf "[%TD %TI:%TM%Tp] %s %p\n" | sort -n | awk '{
    hum[1024**4]="TB"; hum[1024**3]="GB"; hum[1024**2]="MB"; hum[1024]="KB"; hum[0]="B";
    for (x=1024**4; x>=1024; x/=1024){
    if ($3>=x) { printf $1" "$2"\t%7.2f %s\t%s\n",$3/x,hum[x],$4;break }
    }}';

Bu komut dosyaları değiştirilmiş tarihe göre sıralar.

Ve şöyle görün:

[12/05/13 03:10PM] 1.75 MB ./file.text
[12/06/13 11:52PM] 2.90 MB ./file2.mp4
[12/07/13 04:11PM] 4.88 MB ./file3.mp4
[12/07/13 09:17PM] 4.74 MB ./test.apk

Bu komut dosyasını, dosya adlarındaki boşlukları işlemek için geliştirdim, bkz. Superuser.com/a/777007/134532
jan

1

Hem FreeBSD (OS X) hem de Linux için çalışan basit bir çözüme sahibim:

find . -type f -exec ls -t {} +

Bu mükemmel çalışıyor - doğru cevap olmalı ya da en azından daha yüksek puan!
digitaltoast

0

findÇıkış sırasını değiştirmek için herhangi bir seçenek olduğunu sanmıyorum . -mtimeve -mminsonuçları belirli bir zaman dilimi içinde değiştirilmiş dosyalarla sınırlandırmanıza izin verecektir, ancak çıktı sıralanmayacak - bunu kendiniz yapmak zorunda kalacaksınız. GNU find, -printfdiğer şeylerin yanı sıra, bulunan her bir dosyanın değiştirilme zamanını (format dizeleri %tveya %Tk) yazdırmanıza izin verecek bir seçeneğe sahiptir ; findçıktıyı istediğiniz şekilde sıralamanıza yardımcı olabilir .


0

Ben Akaşların cevabını dosya isimlerindeki betiği işleyen boşlukları doğru bir şekilde yaparak cevaplandırdım:

find . -type f -mtime 0 -printf ";[%TD %TI:%TM%Tp];%s;%p\n" | sort -n | awk -F ";" '{
    hum[1024**4]="TB"; hum[1024**3]="GB"; hum[1024**2]="MB"; hum[1024]="KB"; hum[0]="B";
    for (x=1024**4; x>=1024; x/=1024){
    if ($3>=x) { printf $1" "$2"\t%7.2f %s\t%s\n",$3/x,hum[x],$4;break }
    }}';

0

Tüm PNG dosyalarını zaman içinde sipariş etmek istiyorsanız $PWD:

Bu basit tek astar, regexp'in açık findve kapalı tüm esnekliğini sağlar ls.

find $PWD -name "*.png" -print0 | xargs -0 ls -laht | less

0

Sen kullanabilirsiniz statBu şekilde (POSIX üzerine) BSD ve Linux:

$ stat -f "%m%t%N" /[the dir]/* | sort -rn | cut -f2-

Numarayı sınırlamak istiyorsanız:

$ stat -f "%m%t%N" /[the dir]/* | sort -rn | head -[the number] | cut -f2-

0

sort | headBugüne kadar temiz ve sağlam bir yol var :

ls -lGüzel baskı için kullanma

find . ! -type d -printf "%T@ %p\0" |
    sort -zrn |
    head -zn 10 |
    sed -z 's/^[0-9.]\+ //' |
    xargs -0 ls -lt

Bir işlevi olarak:

findByDate() {
    local humansize=''
    [ "$1" = "-h" ] && humansize='h' && shift
    find . ${2:-! -type d} -printf "%T@ %p\0" |
        sort -zrn |
        head -zn ${1:--0} |
        sed -z 's/^[0-9.]\+ //' |
        xargs -0 ls -dlt${humansize}
}

Bu, bir veya iki argümanla veya hatta onsuz çalıştırılabilir.

Usage: findByDate [-h] [lines] [find options]

Numune:

findByDate

Dizine göre olmayan tüm dizinleri listeler . Nota:

Büyük dosya sistemi ağacında bile, xargs alıcının zaten sıralanan bir listesi lsolması halinde , birçok kez çalıştırılsa bile dosya sırası doğru kalır .

findByDate -h 12

Boyutları insan tarafından okunabilir biçimde basılmış, tarihe göre sıralanmış dizin olmayan 12 daha fazla tekrar listelenir

findByDate 42 '-type l'

42 daha fazla tekrarlananları listeleyecek listeler

findByDate -0 '( -type l -o -type b -o -type s -o -type c )'

Tüm sembolik bağlantıları, blok cihazlarını, soketleri ve karakter cihazlarını tarihe göre sıralayarak listeler.

Ters sipariş

Yerine headgöre tailve anahtarı değiştirmek sortve ls:

findByDate() {
    local humansize=''
    [ "$1" = "-h" ] && humansize='h' && shift
    find . ${2:-! -type d} -printf "%T@ %p\0" |
        sort -zn |
        tail -zn ${1:-+0} |
        sed -z 's/^[0-9.]\+ //' |
        xargs -0 ls -dltr${humansize}
}

Aynı fonksiyon, aynı kullanım:

Usage: findByDate [-h] [lines] [find options]

-1

Sadece her bir öğenin tam yolunu bulmak istiyorsanız, bu şekilde yazabilirsiniz.

 find FIND_ROOT -maxdepth 1 -type f -printf "%T@ %p\n" | sort -nr | head -10 | cut -d ' ' -f 2

Burada
-printf "% T @% s \ n" , sıralama kriterleri (tarih) vermek için
'sıralama -NR' tarih ile sıralama için
kafa -10 ilk 10 listeleme sonucu için,
2-f '' -D kesme kesme Her satırda önde gelen zaman damgası.


cut -d ' ' -f 2dosya isimleri boşluk içeriyorsa kırılır.
F. Hauri

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.