Question Unix / Linux trouver et trier par date de modification


Comment puis-je faire un simple find qui commanderait les résultats par les plus récents modifiés?

Voici le courant find J'utilise (je fais une sortie de shell en PHP, donc c'est le raisonnement des variables):

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

Comment pourrais-je avoir cette commande la recherche par la dernière modification? (Remarque: je ne veux pas trier «après» la recherche, mais plutôt trouver les résultats en fonction de ce qui a été le plus récemment modifié.)


103
2018-06-07 18:23


origine


github.com/shadkam/recentmost ferait ce qui est désiré - mais il faut le construire - user3392225


Réponses:


Utilisez ceci:

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

printf arguments de man find:

  • %Tk: Heure de dernière modification du fichier au format spécifié par k.

  • @: secondes depuis le 1 er janvier 1970 à 00:00 GMT, avec fraction partielle.

  • c: date et heure de la locale (sam nov 04 12:02:33 EST 1989).

  • %p: Nom du fichier.


103
2018-02-05 13:31



+1 Très utile, la première réponse à celle que j'ai trouvée avec une sortie de date lisible / utile - Jake N
le plus fiable (et très simple) car le temps est accordé pour être séquentiellement numérique (donc toujours triable), merci! - Aquarius Power
J'ai cet alias pour trouver des fichiers récents dans mon ~/.zshrc: fr () { find ./ -iname "*"$@"*" -printf "%T@ %Td-%Tb-%TY %Tk:%TM %p\n" | sort -n | cut -d " " -f 2- | grep -i "$@" ; } Il trouve de manière récursive tous les fichiers contenant le motif du premier argument passé à la commande (fr <pattern>) et les trie avec la plus récente dernière. - Joel Ostblom
Pour ISO 8601 date de sortie, utilisation find . -printf "%T@ %CY-%Cm-%CdT%CH:%CM:%CS %p\n" | sort -n. Comme il se trie naturellement, il peut également être utilisé directement dans le tri: find . -printf "%CY-%Cm-%CdT%CH:%CM:%CS %p\n" | sort -n - Peter Mortensen


La méthode la plus simple consiste à utiliser zsh, grâce à sa qualificatifs globaux.

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

Si vous avez GNU find, faites-le imprimer les temps de modification des fichiers et triez-les par rapport à cela.

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 newlines comme séparateurs au lieu de null; vous perdrez le support des noms de fichiers contenant des lignes nouvelles.

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

Si vous avez Perl (ici je suppose 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 aucune nouvelle ligne 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 y a 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 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).


80
2018-06-07 18:39



Je pense que le find la version affiche les fichiers les plus anciens, et que vous devez ajouter le -r option à sort. - Quentin Pradet
Mon sed dit qu'il n'a pas d'option -z. - Kef Schecter
@KefSchecter Ensuite, utilisez newlines comme séparateurs, mais vous perdrez la prise en charge des nouvelles lignes dans les noms de fichiers. - Gilles
Ce qui précède est pour python2. Si vous ne disposez que de python3, quelques petites modifications: python3 -c 'import os, sys; times = {} pour f dans sys.stdin.readlines (): f = f [0: -1]; times [f] = os.stat (f) .st_mtime pour f in (trié (times.keys (), key = lambda f: times [f], reverse = True)) [: 10]: print (f); ' - Neil McGill


Vous n'avez pas besoin de PHP ou de Python, juste 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 état d'échec (c.-à-d. Liste d'arguments trop longue), alors vous pouvez itérer avec find. Paraphrasé de: 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 est constituée de chemins longs, absolus ou relatifs, essayez alors de déplacer vos actions dans le répertoire: cd /directory/with/long/path; command * Et une autre solution rapide peut être de faire correspondre moins d’arguments: command [a-e]*; command [f-m]*; ... 


31
2018-06-16 18:11



S'il y a beaucoup de fichiers, cela échoue avec «Liste d'arguments trop longue» sur le ls. - occulus
C'est vrai, mais je crois que la question était "comment puis-je faire une simple découverte ..." - Ярослав Рахматуллин
ls ne cite pas les noms de fichiers d'une manière compréhensible par xargs (pas d'option -0, et les différents styles de citation sont inadéquats) - Tobu


Vous avez seulement besoin ls

Vous pourriez 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`

10
2018-05-18 07:58



S'il y a beaucoup de fichiers, cela échoue avec «Liste d'arguments trop longue» sur le ls. Peut-être recooker pour utiliser xargs? - occulus
Mais si xargs appels ls plusieurs fois, le tri sera cassé. - Aaron D. Marasco
Cela échoue pour les fichiers avec des espaces dans leurs noms. Aucun conseil? - user74094


Extension La réponse de user195696:

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

Pour chaque fichier, cela génère d'abord l'horodatage numérique (pour le tri par suivi de la tabulation) \t), puis un horodatage lisible par l’homme, puis la taille du fichier (malheureusement find's -printf ne peut pas faire en mebibytes, seulement kibibytes), puis le nom de fichier avec chemin relatif.

alors sort -n le trie par le premier champ numérique.

alors cut se débarrasse de 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 champs 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éé un champ de taille de fichier de 6 caractères, car si le fichier est allongé, il devient difficile de distinguer visuellement la taille des fichiers. De cette façon, les fichiers plus grands que 1e6 KiB sortent: par 1 carat signifie 1-9 Go, par 2 caractères signifie 10-99 Go, etc.


Edit: voici une autre version (depuis 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{} provoque l'apparition de {} être remplacé par un argument, et Les nouvelles lignes 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 correctes avec --si).

  • ls -t trie par temps, ce qui n’est pas pertinent ici, mais c’est ce que j’utilise habituellement.


3
2018-04-24 08:12



Note: pour trier par fichier Taille remplacez simplement le T@ par s dans l'une des commandes ci-dessus. - Evgeni Sergeev


Variante OS X de la réponse de @ user195696:

  1. Avec horodatage:

    find . -type f -exec stat -f "%Sm %N" -t "%Y%y%m%d%H%M" {} \; | sort -r
    
  2. 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) }'
    

2
2018-02-24 15:18





J'ai trouvé que cela fait le travail sur Mac OS X (et assez générique pour fonctionner sur d'autres Unixen également):

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

1
2017-07-26 07:42



Malheureusement, cela imprime les noms de mois localisés sur ma configuration croate, rendant le tri incorrect. - Ivan Vučica
La réponse de user195696 travaille pour l'installation croate (et d'autres). - Peter Mortensen


Si ton find la sélection est très simple, vous pourrez peut-être vous en passer et utilisez simplement ls:

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

1
2018-05-02 11:16





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

1
2017-12-08 09:14



J'ai amélioré ce script pour gérer les espaces dans les noms de fichiers, voir superuser.com/a/777007/134532 - jan