11
votes

Quel est le moyen le plus rapide / le plus simple de compter un grand nombre de fichiers dans un répertoire (sous Linux)?

J'ai eu un répertoire, avec un grand nombre de fichiers. Chaque fois que j'ai essayé d'accéder à la liste des fichiers de celui-ci, je n'ai pas pu faire cela ou il y avait un retard important. J'essayais d'utiliser la commande ls code> dans la ligne de commande sous Linux et l'interface Web de mon fournisseur d'hébergement n'a pas aidé également.

Le problème est que lorsque je viens de faire ls Code>, il faut une durée importante pour commencer à afficher quelque chose. Ainsi, ls | WC -L code> ne vous aiderait pas aussi. P>

Après quelques recherches, j'ai proposé ce code (dans cet exemple, il compte le nombre de nouveaux courriels sur certains serveurs): P>

print sum([len(files) for (root, dirs, files) in walk('/home/myname/Maildir/new')])


2 commentaires

Voulez-vous compter à la fois le nombre de fichiers et le nombre de répertoires?


@Rafe Peu importe - l'annuaire dont je parle n'a pas de sous-répertoires. Ainsi, les deux solutions me sont égales.


7 Réponses :


0
votes

Je ne suis pas sûr de la vitesse, mais si vous voulez simplement utiliser Shell comité, cela devrait fonctionner:

#!/bin/sh
COUNT=0;
for file in /path/to/directory/*
do
COUNT=$(($COUNT+1));
done
echo $COUNT


0 commentaires

7
votes

ls est un stat (2) appeler chaque fichier. D'autres outils, tels que Rechercher (1) et l'expansion de Wildcard Shell, peuvent éviter cet appel et juste faire readdir . Une combinaison de commandes shell qui pourrait fonctionner est Trouver Dir -MaxDepth 1 | WC -L , mais il répertorier volontiers le répertoire lui-même et répertorier tout nom de fichier avec une nouvelle ligne.

de Python, le moyen simple d'obtenir juste ces noms est Os.listdir (Répertoire) . Contrairement à Os.walk et Os.Path.Walk, il n'a pas besoin de recueil, de vérifier les types de fichiers ou de faire d'autres appels de fonction Python.

addendum: il semble que LS ne stire pas toujours. Au moins sur mon système GNU, il ne peut faire qu'un appel de getdents lorsque des informations complémentaires (telles que les noms des annuaires) ne sont pas demandées. getdents est l'appel système sous-jacent utilisé pour implémenter le readdir à GNU / Linux.

Ajout 2: une raison d'un retard avant les résultats des sorties LS est qu'il trie et tabule. LS -U1 peut éviter cela.


0 commentaires

4
votes

Nombre total de fichiers dans le répertoire donné

find . -type f | wc -l


0 commentaires

1
votes

Je pense que ls passe la majeure partie de son temps avant d'afficher la première ligne car il doit trier les entrées, donc ls -u devrait afficher la première ligne beaucoup plus rapide (Bien que ce ne soit peut-être pas aussi mieux au total).


0 commentaires

4
votes

Ceci devrait être assez rapide en python: xxx


0 commentaires

1
votes

Le moyen le plus rapide serait d'éviter toute surcharge des langages interprétées et d'écrire du code qui répond directement à votre problème. Cela est difficile à faire de manière portable, mais assez simple. Pour le moment, je suis sur une boîte d'OS X, mais la conversion des éléments suivants en Linux devrait être extrêmement simple. (J'ai choisi d'ignorer des fichiers cachés et de ne compter que des fichiers réguliers ... Modifier le besoin ou d'ajouter des commutateurs de ligne de commande pour obtenir la fonctionnalité souhaitée.)


#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>

int
main( int argc, char **argv )
{
    DIR *d;
    struct dirent *f;
    int count = 0;
    char *path = argv[ 1 ];

    if( path == NULL ) {
        fprintf( stderr, "usage: %s path", argv[ 0 ]);
        exit( EXIT_FAILURE );
    }
    d = opendir( path );
    if( d == NULL ) { perror( path );exit( EXIT_FAILURE ); }
    while( ( f = readdir( d ) ) != NULL ) {
        if( f->d_name[ 0 ] != '.'  &&  f->d_type == DT_REG )
            count += 1;
    }
    printf( "%d\n", count );
    return EXIT_SUCCESS;
}


3 commentaires

Bien que je n'ai pas une image complète de l'endroit où se passe ce code, la complexité pure de ce bit de C est un signe d'avertissement. En outre, la page de contrôle de l'homme de Readdir (3) montre que d_type pourrait être dt_unknown pour quoi que ce soit, et vous avez besoin de _Bsd_source de l'utiliser avec des systèmes GNU (autres * Nixes peut ne pas l'avoir du tout). Interprète nonobstant, le niveau d'abstraction plus élevé peut rendre Python un meilleur outil ici.


La question est la suivante: "Quel est le moyen le plus rapide de le faire?" Une implémentation C écrasera Python pour la vitesse du temps d'exécution.


Le plus rapide / plus facile, en fait. Je ne serais pas surpris que le temps de déploiement compte plus que le temps de la CPU (qui va différer plus que l'exécution). Le travail est I / O lié de toute façon. Ne pas contester que c est en cours d'exécution plus efficace, il suffit de noter que c'est plus de travail pour bien écrire.



0
votes

Mon étui d'utilisation est un fichier de comptage Linux SBC (Banana PI) dans un répertoire sur un bâton USB FAT32. Dans une coquille, faire

t=time.time() ; print len(os.listdir(d)) ; print time.time()-t


0 commentaires