Wie kann ich eine einfache find
erstellen, die die Ergebnisse nach den zuletzt geänderten ordnet?
Hier ist die aktuelle find
, die ich verwende (ich führe eine Shell-Escape-Operation in PHP durch, also ist dies die Begründung für die Variablen):
find '$dir' -name '$str'\* -print | head -10
Wie kann ich diese Reihenfolge ändern lassen, indem ich die Suche zuletzt ändere? (Hinweis: Ich möchte nicht, dass nach der Suche sortiert wird, sondern dass die Ergebnisse auf der Grundlage der zuletzt vorgenommenen Änderungen gefunden werden.)
Benutze das:
find . -printf "%[email protected] %Tc %p\n" | sort -n
printf
Argumente aus man find
:
%Tk
: Der letzte Änderungszeitpunkt der Datei in dem durch k
angegebenen Format.
@
: Sekunden seit dem 1. Januar 1970, 00:00 GMT, mit Bruchteilen.
c
: Datum und Uhrzeit des Gebietsschemas (Sat Nov 04 12:02:33 EST 1989).
%p
: Dateiname.
Die einfachste Methode ist die Verwendung von zsh dank der glob-Qualifikationsmerkmale .
print -lr -- $dir/**/$str*(om[1,10])
Wenn Sie GNU find haben, lassen Sie es die Dateiänderungszeiten drucken und danach sortieren.
find -type f -printf '%[email protected] %p\0' |
sort -zk 1nr |
sed -z 's/^[^ ]* //' | tr '\0' '\n' | head -n 10
Wenn Sie GNU, aber keine anderen GNU Hilfsprogramme finden, verwenden Sie Zeilenumbrüche als Trennzeichen anstelle von Nullen. Sie verlieren die Unterstützung für Dateinamen mit Zeilenumbrüchen.
find -type f -printf '%[email protected] %p\n' |
sort -k 1nr |
sed 's/^[^ ]* //' | head -n 10
Wenn Sie Perl haben (hier gehe ich davon aus, dass die Dateinamen keine Zeilenumbrüche enthalten):
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];
}'
Wenn Sie Python haben (auch wenn Sie keine Zeilenumbrüche in den Dateinamen voraussetzen):
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'
Es gibt wahrscheinlich eine Möglichkeit, dasselbe in PHP zu tun, aber ich weiß es nicht.
Wenn Sie nur mit POSIX-Tools arbeiten möchten, ist dies etwas komplizierter. siehe Wie man Dateien rekursiv nach Änderungsdatum sortiert auflistet (kein stat-Befehl verfügbar!) (das erneute Verknüpfen der ersten 10 ist der einfache Teil).
Sie brauchen weder PHP noch Python, nur 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 "{}" +;
Wenn der Befehl * mit einem Fehlerstatus beendet wird (dh Argumentliste zu lang ), können Sie mit find iterieren. Umschrieben aus: Die maximale Länge der Argumente für einen neuen Prozess
find . -print0|xargs -0 command
(optimiert die Geschwindigkeit, wenn find "-exec +" nicht implementiert, aber "-print0" kennt)find . -print|xargs command
(wenn die Argumente keine Leerzeichen enthalten)Wenn der größte Teil der Argumente aus langen, absoluten oder relativen Pfaden besteht, versuchen Sie, Ihre Aktionen in das Verzeichnis zu verschieben: cd /directory/with/long/path; command *
Eine weitere schnelle Lösung könnte darin bestehen, weniger Argumente zu finden: command [a-e]*; command [f-m]*; ...
Sie brauchen nur ls
Sie könnten find /wherever/your/files/hide -type f -exec ls -1rt "{}" +;
wie oben angegeben tun,
oder
ls -1rt `find /wherever/your/file/hides -type f`
Erweiterung der Antwort von user195696 :
find . -type f -printf "%[email protected]\t%Tc %6k KiB %p\n" | sort -n | cut -f 2-
Für jede Datei wird zuerst der numerische Zeitstempel (zum Sortieren nach, gefolgt von der Tabellierung \t
), dann ein lesbarer Zeitstempel, dann die Dateigröße (der -printf
von find
ist leider nicht in Mebibytes möglich, nur in Kibibytes) und dann der Dateiname mit ausgegeben relativer Pfad.
Dann sortiert sort -n
es nach dem ersten numerischen Feld.
Dann entfernt cut
das erste numerische Feld, das für den Benutzer nicht von Interesse ist. (Druckt das zweite Feld weiter.) Das Standardfeldtrennzeichen ist \t
oder tabellarisch.
Ausgabebeispiel:
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
Ich habe das Feld mit der Dateigröße absichtlich auf 6 Zeichen erweitert, da bei einer längeren Länge die visuelle Unterscheidung der Dateigröße schwierig wird. Auf diese Weise ragen Dateien über 1e6 KiB heraus: 1 Zeichen bedeutet 1-9 GB, 2 Zeichen bedeuten 10-99 GB usw.
Edit: hier ist eine andere Version (da find . -printf "%Tc"
unter MinGW/MSYS abstürzt):
find . -type f -printf "%[email protected]\t%p\n" | sort -n | cut -f 2- | xargs -I{} ls -Glath --si {}
Ausgabe geben wie:
-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
Woher:
-I{}
bewirkt, dass das Vorkommen von {}
durch ein Argument ersetzt wird. und Zeilenumbrüche sind jetzt die Argumenttrennzeichen (beachten Sie die Leerzeichen in den obigen Dateinamen).
ls -G
unterdrückt das Drucken des Gruppennamens (Platzverschwendung).
ls -h --si
erzeugt lesbare Dateigrößen (genauer mit --si
).
ls -t
sortiert nach Zeit, was hier irrelevant ist, aber das ist es, was ich normalerweise benutze.
OS X-Variante der Antwort von @ user195696:
Mit Zeitstempel:
find . -type f -exec stat -f "%Sm %N" -t "%Y%y%m%d%H%M" {} \; | sort -r
Ohne Zeitstempel:
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) }'
Versuchen:
find '$dir' -name '$str'\* -print | xargs ls -tl | head -10
Es ist aber auch nützlich, Daten nach -mmin
/-mtime
und -type
zu filtern.
Wenn Ihre find
-Auswahl sehr einfach ist, können Sie möglicherweise darauf verzichten und einfach ls
verwenden:
ls -1 *.cc # -r -t optional
Ich stellte fest, dass dies unter Mac OS X erledigt wird (und generisch genug, um auch unter anderen Unixen zu funktionieren):
find . -type f -ls | awk '{print $(NF-3), $(NF-2), $(NF-1), $NF}' | sort
Benutzen:
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 }
}}';
Dieser Befehl sortiert Dateien nach Änderungsdatum.
Und wie folgt darstellen:
[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
Ich glaube nicht, dass find
Optionen zum Ändern der Ausgabereihenfolge hat. Mit -mtime
und -mmin
können Sie die Ergebnisse auf Dateien beschränken, die innerhalb eines bestimmten Zeitfensters geändert wurden. Die Ausgabe wird jedoch nicht sortiert - Sie müssen dies selbst tun. GNU find
verfügt über eine -printf
-Option, mit der Sie unter anderem die Änderungszeit jeder gefundenen Datei drucken können (Formatzeichenfolgen %t
oder %Tk
). Das kann Ihnen helfen, die Ausgabe von find
nach Ihren Wünschen zu sortieren.
Ich habe Akashs Antwort verbessert, indem ich das Skript so eingestellt habe, dass es Whitespace in Dateinamen korrekt verarbeitet:
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 }
}}';
Sie können stat
unter BSD und Linux (nicht unter POSIX) folgendermaßen verwenden:
$ stat -f "%m%t%N" /[the dir]/* | sort -rn | cut -f2-
Wenn Sie die Anzahl begrenzen möchten:
$ stat -f "%m%t%N" /[the dir]/* | sort -rn | head -[the number] | cut -f2-
Wenn Sie alle PNG-Dateien nach Zeit in $PWD
bestellen möchten:
Dieser einfache Einzeiler bietet die Flexibilität von regulären Ausdrücken für find
und ls
.
find $PWD -name "*.png" -print0 | xargs -0 ls -laht | less