Comment fonctionne `wc -l`?

11

Je dois lire un gros fichier et avant de commencer à le lire, j'ai besoin de connaître le nombre total de lignes dans le fichier (qui sont en millions).

J'ai mis en place de nombreuses solutions et j'en ai trouvé une. Mais pendant ma recherche, je pensais voir comment ça wc -lmarche. Je n'ai rien trouvé sur Google.

Bien que j'aie trouvé une solution à mon problème, j'aimerais quand même savoir comment ça wc -lmarche car il peut calculer le nombre de lignes d'un fichier de 92 millions de lignes en quelques secondes!

Comment?

détraqueur
la source

Réponses:

20

Il lit le fichier entier et compte le nombre de fins de ligne. Compter les fins de ligne est vraiment bon marché; la plupart du temps passé à lire le fichier. Si le fichier se trouve (principalement) dans le cache de tampon, ce sera aussi bon marché. Sinon, cela dépendra de la vitesse de stockage de vos fichiers.

En d'autres termes, il n'y a pas de magie.

rici
la source
Il lit le fichier entier et compte le nombre de fins de ligne? Pour arriver à la fin de la ligne, ne lit-elle pas fondamentalement toute la ligne jusqu'à la fin? Et cela signifierait qu'il lirait le dossier entier, non?
detraveller
@detraveller: oui, il lit tout le fichier, comme je l'ai dit. Il ne le lit pas ligne par ligne ou en une seule fois, mais il lit chaque caractère et compte combien de ces caractères sont des caractères de fin de ligne.
rici
7

WC lit simplement le fichier en blocs d'octets bruts (de préférence en multiples de la taille de bloc naturelle du système de fichiers sous-jacent sur lequel se trouve le fichier).
Ensuite, il balaye simplement le tampon en comptant les caractères de fin de ligne. (Il compte également les espaces, les tabulations, les flux de formulaires et d'autres caractères spéciaux, juste au cas où vous souhaiteriez d'autres informations que la sortie -l.)

La lecture à partir du disque est la partie coûteuse en termes de vitesses. L'analyse du tampon prend un temps négligeable par rapport à cela.

Supposons que vous ayez 90 millions de lignes avec en moyenne 100 caractères par ligne.
Cela représente environ 9 000 000 000 de caractères, soit environ 860 Mo.
Un PC décent avec un lecteur SATA-3Gb / s le fera en moins de 10 secondes. Même sur un système de fichiers relativement lent avec une autre activité en cours en même temps.
Une machine rapide avec un réglage des performances et un système de fichiers optimisé peut le faire en moins de 5 secondes, même sans avoir à recourir à SATA-6G et à un lecteur SSD.

Tonny
la source
il balaye simplement le tampon en comptant les caractères de fin de ligne ( \n) - "-l, --lines affiche le nombre de sauts de ligne \ n \" - extrait dewc.c
Rahul Patil
@RahulPatil La plupart des implémentations font bien plus que simplement compter les nouvelles lignes. Voir l'exemple mentionné dans le premier commentaire ci-dessus. C'est la source de wc utilisée dans les utilitaires de base Linux.
Tonny
oui .. j'ai vu ça .. je mentionne juste parce que, question sur wc -l.. désolé ...
Rahul Patil
3

Bienvenue dans le monde du logiciel libre. Vous pouvez toujours regarder le code source

Bien que je dois admettre que je ne suis pas un programmeur C, je ne suis donc pas celui qui peut vraiment vous expliquer le code (et je serais moi-même intéressé).

Ce que je sais, c'est que puisque wc n'ouvre pas le fichier lui-même, mais demande au système d'exploitation de le faire, cela dépend en grande partie du système d'exploitation et, bien sûr, de la façon dont le fichier est stocké. En dehors de cela, je m'attends à ce que des pratiques de programmation correctes soient en place, par exemple, ne pas essayer de lire le fichier dans son ensemble à la fois, etc.

Alois Mahdal
la source
Que voulez-vous dire par «ne pas essayer de lire tout le fichier à la fois»?
detraveller
Je veux dire le chargement du fichier en mémoire, par exemple, sur une seule chaîne / tableau. Dans la communauté Perl, cela s'appelle slurping, et c'est une solution rapide et sale qui est OK quand vous savez que vous lirez quelques lignes, mais alimenter un fichier vraiment énorme en mémoire à la fois est rarement une bonne idée.
Alois Mahdal
1
D'un autre côté, vous pouvez lire, disons, 64 Ko, compter les nouvelles lignes et les jeter, répéter ... De cette façon, vous mangerez au maximum 64 Ko, quelle que soit la taille du fichier. (C'est moins facile quand vous vous rendez compte que le saut de ligne peut avoir 2 octets et donc devenir divisé en 2 morceaux; c'est maintenant que le plaisir commence)
Alois Mahdal
Pas trop important, mais: "puisque wc n'ouvre pas le fichier lui-même, mais demande au système d'exploitation de le faire" - je ne sais pas ce que vous entendez par là, mais je doute que ce soit correct. C'est certainement lire tous les personnages par lui-même.
Arjan
2
@Arjan Bien que, pour être vraiment correct: à l'exclusion des systèmes embarqués, les programmes ne font pas vraiment la lecture eux-mêmes, tout l'intérêt du noyau et du système d'exploitation est qu'il fait le travail pour eux. En fait, open (), close (), read () (que ce soit Linux, Windows, socket ou fichier) sont tous des appels système que les programmes réels n'ont aucune idée du fonctionnement interne.
Alois Mahdal