Meilleure façon de répertorier 100 premiers fichiers dans un répertoire triés par heure

12

Quelle serait la meilleure façon de répertorier 100 premiers fichiers dans un répertoire trié par l'horodatage créé (le plus ancien en premier). Le répertoire est assez volumineux (environ 100 000 fichiers).

ls passe à la tête prend beaucoup de temps pour terminer.

Éditer:

  • Le système de fichiers est ext3.
  • limiter le nombre de fichiers dans le dossier ne vaut pas la peine, car cela va être une opération de "nettoyage" rare et les fichiers sont générés par un logiciel tiers.
  • L'utilisation de l' heure de modification du fichier , au lieu de l' heure de création, fournit une solution acceptable.


la source
1
Si c'est une opération de nettoyage, peut-être que vous voulez simplement find -mtime +<number of days> -deletenettoyer tous les fichiers plus anciens qu'un certain âge. Cela signifie qu'aucun tri n'est nécessaire.
Mikel

Réponses:

14

Vous dites que " ls passe à la tête prend beaucoup de temps pour terminer".

La cause n'est pas ls, mais le nombre de fichiers dans votre répertoire. Si vous avez 100 000 fichiers dans un seul répertoire, tout moyen de résoudre ce problème devrait obtenir des informations sur les 100 000 fichiers avant même de penser à les trier ou à imprimer une sortie.

Si cela prend trop de temps, la vraie solution est de diviser les fichiers sur plusieurs répertoires.

Si vous ne pouvez pas répartir les fichiers sur plusieurs répertoires, existe-t-il un moyen de réduire le nombre de fichiers à considérer ? Par exemple, si les noms de fichiers incluent une date, vous pouvez peut-être inclure un caractère générique afin que le système n'ait pas à trier 100 000 fichiers. Ou peut-être qu'ils sont numérotés séquentiellement? (Cela peut ou peut ne pas aider, mais cela vaut la peine d'essayer.)

Combien de fois essayez-vous de faire cela? Peut-être que cela vaut la peine de sauvegarder / mettre en cache la sortie pour la réutiliser .


Maintenant, une question.

Êtes-vous sûr de vouloir dire «heure de création» et non pas «heure de changement» ? La plupart des outils ne peuvent afficher que le "temps de changement", pas le "temps de création".

Obtenir le «temps de création» est une toute nouvelle chose, qui nécessite un système de fichiers ext4 et certains outils qui ne sont pas faciles à installer.


Si vous voulez changer l'heure

Changer l'heure (ctime pour faire court) signifie l'heure de la dernière modification des attributs du fichier.

ls -c trie par ctime.

Vous voulez que la sortie soit dans l'ordre croissant et non décroissant, vous devez donc inverser la sortie avec l' -roption également.

Vous pouvez donc le faire comme ceci:

ls -cr | head -n 100

Une solution plus longue au même problème en utilisant stat:

find . -mindepth 1 -maxdepth 1 -exec stat -c $'%Z\t%n' '{}' \; |
    sort -k 1n |
    cut -f 2 -d $'\t' |
    head -n 10 |
    sed -e 's/^\.\///'

mais cela fonctionne plus lentement que ls -crsur mon système.


Si vous voulez du temps de modification

L'heure de modification (mtime pour faire court) signifie l'heure à laquelle le contenu du fichier a été modifié pour la dernière fois.

ls -t trie par mtime.

Passez ls -crà ls -tr(meilleure option) ou passez stat -c $'%Z\t%n'à stat -c $'%Y\t%n'.


Si vous avez besoin de temps de création

(crtime pour faire court)

C'est plus difficile.

Tout d'abord, assurez-vous que le répertoire se trouve sur un système de fichiers formaté à l'aide de ext4. Vous pouvez utiliser tune2fs -l <device name>pour vérifier cela.

Ensuite, il existe un nouveau statformat appelé %W, qui peut vous aider ici. Pour l'obtenir, vous devrez télécharger une version de GNU Coreutils sortie en octobre 2010 ou après, l'extraire, la compiler et l'installer.

Ensuite, selon votre noyau, cela pourrait fonctionner (je ne l'ai pas essayé).

find . -mindepth 1 -maxdepth 1 -exec stat -c $'%W\t%n' '{}' \; |
    sort -k 1n |
    cut -f 2 -d $'\t' |
    head -n 10 |
    sed -e 's/^\.\///'

Voir également:


Si vous obtenez des erreurs "'$\t'

La '$\t'notation nécessite bashou zsh: elle ne fonctionnera pas dans dashou shsur Ubuntu. Si vous avez vraiment besoin d'utiliser ces shells, vous devrez remplacer n'importe quel \tpar Ctrl+ V, Tabet supprimer le $début juste avant le devis d'ouverture.

Mikel
la source
Il est possible qu'il n'exécute pas ext4. J'exécute Ubuntu 10.04 sur toutes mes machines, mais j'exécute JFS sur plusieurs lecteurs. AFAIK JFS prend en charge les horodatages de création.
jwernerny
En effet. Nous savons qu'il n'est pas pris en charge sur ext3 et qu'il est pris en charge sur ext4. Une recherche rapide suggère que cela pourrait fonctionner avec zfs ou les ufs FreeBSD, mais aucun de ceux-ci n'est courant sur Ubuntu! Je ne sais pas pour jfs ou xfs ou quoi que ce soit d'autre. Serait heureux d'en savoir plus si vous pouvez trouver des informations / liens.
Mikel
Merci pour cette réponse très complète et pour le rappel subtil d'écrire des questions plus spécifiques;) "Find" s'est avéré être un gagnant en termes de performances, le type fs s'est avéré être ext3.
2

Une autre façon, si l'on trouve de faire des choses aujourd'hui, pourrait être pertinente pour vos problèmes de performances:

I=0; ls -cr /dir/ | while read file; do I=`expr $I + 1`; echo "$file"; if [ $I == 100 ]; then break; fi; done

Cela devrait en théorie commencer à sortir beaucoup plus rapidement, mais je suppose que cela dépend d'où vient le décalage. Le lstri des fichiers peut prendre du temps.

Oli
la source
J'en doute. headquitte en fait dès qu'il a lu suffisamment d'entrée. Essayez de courir les deux avec timeà l'avant. La headversion est de toute façon beaucoup plus rapide sur mon système.
Mikel