Comment puis-je faire une simple find
qui ordonnerait les résultats les plus récemment modifiés?
Voici la find
actuelle que j'utilise (je fais un échappement Shell en PHP, donc c'est le raisonnement pour les variables):
find '$dir' -name '$str'\* -print | head -10
Comment pourrais-je avoir cette commande la dernière recherche modifiée? (Remarque: je ne souhaite pas qu'il trie "après" la recherche, mais trouve les résultats en fonction de ce qui a été modifié le plus récemment.)
Utilisez ceci:
find . -printf "%T@ %Tc %p\n" | sort -n
printf
arguments from man find
:
%Tk
: heure de dernière modification du fichier au format spécifié par k
.
@
: secondes depuis le 1er janvier 1970 à 00h00 GMT, avec partie fractionnaire.
c
: date et heure de la localisation (sam 4 nov. 12:02:33 EST 1989).
%p
: nom du fichier.
La méthode la plus simple consiste à utiliser zsh, grâce à ses qualificatifs glob .
print -lr -- $dir/**/$str*(om[1,10])
Si vous avez GNU find, faites-le imprimer les temps de modification du fichier et triez-le.
find -type f -printf '%T@ %p\0' |
sort -zk 1nr |
sed -z 's/^[^ ]* //' | tr '\0' '\n' | head -n 10
Si vous avez GNU find mais pas d'autres utilitaires GNU, utilisez des nouvelles lignes comme séparateurs au lieu de NULL; vous perdrez la prise en charge des noms de fichiers contenant des nouvelles lignes.
find -type f -printf '%T@ %p\n' |
sort -k 1nr |
sed 's/^[^ ]* //' | head -n 10
Si vous avez Perl (ici, je supposerai qu'il n'y a pas de nouvelles lignes dans les noms de fichiers):
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];
}'
Si vous avez Python (en supposant également qu'il n'y a pas de nouvelles lignes dans les noms de fichiers):
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'
Il existe probablement un moyen de faire la même chose en PHP, mais je ne le sais pas.
Si vous voulez travailler uniquement avec les outils POSIX, c'est un peu plus compliqué. voir Comment lister les fichiers triés par date de modification de manière récursive (aucune commande stat disponible!) (retatiner les 10 premiers est la partie facile).
Vous n'avez pas besoin de PHP ou de Python, seulement 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 "{}" +;
Si la commande * se termine avec un statut d'échec (par exemple, La liste d'arguments est trop longue ), vous pouvez effectuer une itération avec find. Paraphrased from: La longueur maximale des arguments pour un nouveau processus
find . -print0|xargs -0 command
(optimise la vitesse, si find n'implémente pas "-exec +" mais connaît "-print0")find . -print|xargs command
(s'il n'y a pas d'espace blanc dans les arguments)Si la majeure partie des arguments consiste en des chemins longs, absolus ou relatifs, essayez de déplacer vos actions dans le répertoire: cd /directory/with/long/path; command *
Une autre solution rapide consiste à faire correspondre moins d'arguments: command [a-e]*; command [f-m]*; ...
Vous avez seulement besoin de ls
Vous pouvez faire find /wherever/your/files/hide -type f -exec ls -1rt "{}" +;
comme indiqué ci-dessus,
ou
ls -1rt `find /wherever/your/file/hides -type f`
Extension de réponse de user195696 :
find . -type f -printf "%T@\t%Tc %6k KiB %p\n" | sort -n | cut -f 2-
Pour chaque fichier, cela commence par afficher l’horodatage numérique (pour trier par, suivi de la tabulation \t
), puis un horodatage lisible par l’homme, puis la taille du fichier (malheureusement, le -printf
du find
ne peut pas être exprimé en mégaoctets, uniquement le kibibytes), puis le nom de fichier avec chemin relatif.
Ensuite, sort -n
le trie en fonction du premier champ numérique.
Ensuite, cut
supprime ce premier champ numérique qui n’a aucun intérêt pour l’utilisateur. (Imprime le deuxième champ en avant.) Le séparateur de champ par défaut est \t
ou tabulation.
Exemple de sortie:
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
J'ai délibérément créé 6 caractères pour le champ de taille de fichier, car si on le rend plus long, il devient difficile de distinguer visuellement la taille des fichiers. Ainsi, les fichiers dont la taille est supérieure à 1e6 Ko font saillie: par 1 caractère signifie entre 1 et 9 Go, par 2 caractères, entre 10 et 99 Go, etc.
Edit: voici une autre version (depuis que find . -printf "%Tc"
se bloque sur MinGW/MSYS):
find . -type f -printf "%T@\t%p\n" | sort -n | cut -f 2- | xargs -I{} ls -Glath --si {}
Donner une sortie comme:
-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
Où:
-I{}
fait que l'occurrence de {}
soit remplacée par un argument, et / newlines sont maintenant les séparateurs d'arguments (notez les espaces dans les noms de fichiers ci-dessus).
ls -G
supprime l’impression du nom du groupe (perte d’espace).
ls -h --si
produit des tailles de fichier lisibles par l'homme (plus correct avec --si
).
ls -t
trie par heure, ce qui est sans importance ici, mais c'est ce que j'utilise généralement.
Variante OS X de la réponse de @ user195696:
Avec horodatage:
find . -type f -exec stat -f "%Sm %N" -t "%Y%y%m%d%H%M" {} \; | sort -r
Sans horodatage:
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) }'
Essayer:
find '$dir' -name '$str'\* -print | xargs ls -tl | head -10
Mais il est également utile de filtrer les données par -mmin
/-mtime
et -type
.
Si votre sélection find
est très simple, vous pourrez peut-être vous en passer et utilisez simplement ls
:
ls -1 *.cc # -r -t optional
J'ai constaté que cela se faisait sous Mac OS X (et suffisamment générique pour fonctionner également sur d'autres Unixen):
find . -type f -ls | awk '{print $(NF-3), $(NF-2), $(NF-1), $NF}' | sort
Utilisation:
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 }
}}';
Cette commande va trier les fichiers par date de modification.
Et afficher comme:
[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
Je ne pense pas que find
dispose d’options pour modifier l’ordre de sortie. -mtime
et -mmin
vous permettront de limiter les résultats aux fichiers modifiés au cours d'une certaine période, mais le résultat ne sera pas trié - vous devrez le faire vous-même. GNU find
a une option -printf
qui, entre autres choses, vous permettra d’imprimer l’heure de modification de chaque fichier trouvé (chaîne de format %t
ou %Tk
); cela peut vous aider à trier la sortie find
comme vous le souhaitez.
J'ai amélioré la réponse Akash en rendant le script gérant correctement les espaces dans les noms de fichiers:
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 }
}}';
Vous pouvez utiliser stat
sous BSD et Linux (pas sous POSIX) de cette manière:
$ stat -f "%m%t%N" /[the dir]/* | sort -rn | cut -f2-
Si vous voulez limiter le nombre:
$ stat -f "%m%t%N" /[the dir]/* | sort -rn | head -[the number] | cut -f2-
Si vous souhaitez commander tous les fichiers PNG par heure dans $PWD
:
Ce simple one-liner donne toute la flexibilité de l'expression rationnelle sur find
et sur ls
.
find $PWD -name "*.png" -print0 | xargs -0 ls -laht | less