oui enfin je me suis mal exprimé en fait je "voulais" l'equivalent en perl d'un du -h justement parceque la ca donne des chiffre immense pas tres lisible.
mea culpa
$ ls -lRa
.:
total 1632
drwxr-xr-x 3 jmfayard jmfayard 4096 2003-12-02 20:07 .
drwxr-xr-x 75 jmfayard jmfayard 4096 2003-12-02 20:02 ..
-rw-r--r-- 1 jmfayard jmfayard 50750 2003-11-09 17:17 a
[... idem ...]
./Tests:
total 420
drwxr-xr-x 2 jmfayard jmfayard 4096 2003-11-09 18:01 .
drwxr-xr-x 3 jmfayard jmfayard 4096 2003-12-02 20:07 ..
-rw-r--r-- 1 jmfayard jmfayard 2076 2003-11-09 18:01 pat2.xml
[... idem ...]
$ perl -e 'TRUC' ==> excuter l'argument TRUC et non pas un fichier
$ perl -lap
Equivalent de
#!/usr/bin/perl
while( <> ) { # perl -p : on fait une boucle autour de
# chaque ligne de STDIN ou des fichiers en arguments
chomp; # perl -l : on limine la fin de ligne
@F = split; # perl -a : F contient la liste des mots de la ligne courante
[... reste du script en argument ici ... ]
print ; # perl -p ["print"] : on affiche la ligne $_ modifie par le script
# prcdent.
# perl -n fait aussi une boucle autour du programme sans imprimer
# automatiquement la fin.
}
Donc on analyse chaque ligne sachant que la liste des mots se trouvent dans @F
Reste analyser le reste du script :
$ /^total/?$x+=$F[1]:$x}{$_=$x'
Arghh
Segmentation Fault de mon cerveau.
Core Dumped
Bon avanons pas pas :
on peut arriver reconnatre la structure (...) ? (...) : (...)
qui vient du C.
La condition est facile :
/^total/ ==> si la ligne courante commence par total
Si elle est remplie, on excute :
$x += $F[1]
Bon, c'est clair, on a un compteur qui additione le deuxime mot aprs total
Dans mon exemple :
[...]
total 1632
[...]
total 420
[...]
Sinon, on excute :
$x}{$_=$x
Vous ne rvez pas, a ne veut rien dire.
Il y a un vieux hack l-dessous. Reprenons, perl -p -e SCRIPT correspond en fait :
#!/usr/bin/perl
while( <> )
{
SCRIPT
print $_;
}
Que se passe-t'il s'il y a "}{" dans SCRIPT ?
Disons : SCRIPT ::= DEBUT "}" "{" CONTINUE
Notre code correspond maintenant :
#!/usr/bin/perl
while( <> )
{
DEBUT
}
{
CONTINUE
print $_;
}
Astucieux et dgeulasse, non ?
C'est pour cel que CONTINUE correspond :
$_ = $x ; # notre brave compteur qu'il faut imprimer.
Voil, cette fois on a tout, la version lisible est :
#!/usr/bin/perl -w
use Strict;
my $x = 0; # compteur
my $ligne;
while( $ligne=<> )
{
chomp;
@F = split / */, $ligne ;
if ( $ligne =~ /^total)
{
$x += $F[1] ;
}
}
{
print $x;
}
PS: Le copier-coller sous Linusque suxor. Il n'y a pas que le plain ascii dans la vie.
oui, c'est ça :-) c'est vrai que c'est un peu plus lisible comme ça.
pour le }{$_=$x' c'est juste pour sortir de la boucle du -p et initialiser $_ pour l'afficher ensuite (toujours le -p), bon, il manque il manque quelques points virgules aussi, mais on est pas à ça pret !
Vive le perl :) A noter que chez moi cet uniligne et presque aussi rapide qu'un du, mais semble plus précis :
par exemple, pour /usr le script ce termine 1 seconde apres et les résultats sont :
du : 2975040
perl : 3026770
C'est marrant, ça, sur le vieux serveur de mail de ma boite (un pentium 133 ou quelque chose comme ça) le du et le ls sont en gros aussi rapide
sur ma bécane (XP1800+) le du est moins de 10 secondes plus rapide sur environs 30 Go de fichiers. bon, j'imagine que ton disque dur n'est vraiment pas une foudre de guerre...
j'est çà :
[/usr]$ time -p du
[...]
2975040 .
real 31.55
user 0.34
sys 2.60
[usr]$ time -p ls -lRa|perl -aple '/^total/?$x+=$F[1]:$x}{while($x>1024){$x/=1024}$_=$x'
real 19.38
user 2.93
sys 2.83
2.88655281066895
Mais en effet, pour des très grosse quantité, l'uniligne et plus longue en général)
Pour le plus précis, en effet, je risque de compter plusieurs fois les liens durs, et je ne l'ai pas pris en compte. pour rappel les liens dur dont tu parle sont les ./ ../ c'est ça ?
En effet, à cause du -a du ls, ils sont listés donc comtabilisés, mea culpa, il faut donc faire un ls -A pour ne plus les avoir.
Sinon, je ne voit pas d'autre liens dur (c'est plutôt rare, avec les liens symboliques...)
Bon, j'ai pas encore des résultats comme sur windows : 30Go occupé, 43 To de libres (sur un disque de 40 Go) ;)
et puis les résultats varie quand même grandement :
[mitsuaki]$ time -p ls -lRa|perl -aple '/^total/?$x+=$F[1]:$x}{while($x>1024){$x/=1024}$_=$x' real 7.05
user 0.45
sys 0.62
1.19140148162842
[mitsuaki]$ time -p ls -lRA|perl -aple '/^total/?$x+=$F[1]:$x}{while($x>1024){$x/=1024}$_=$x' real 1.49
user 0.43
sys 0.27
1.18892002105713
tient, j'ai mis le -a et le -A, y'a quand même une bonne différence, merci de la remarque :)
# Re: du en perl
Posté par Nick Depp . Évalué à 1.
la meme chose en human readable ?
[^] # Re: du en perl
Posté par AlphA . Évalué à 2.
du
[^] # Re: du en perl
Posté par Ramso . Évalué à 3.
[^] # Re: du en perl
Posté par Nick Depp . Évalué à 1.
mea culpa
[^] # Re: du en perl
Posté par Ramso . Évalué à 1.
[^] # Re: du en perl
Posté par Matthieu BENOIST . Évalué à 2.
ls -lRa|perl -aple '/^total/?$x+=$F[1]:$x}{while($x>1024){$x/=1024}$_=$x'
mais doit y avoir une façon plus concise de le dire. Par contre, là, c'est à vous de deviner les unités :)
# J'ai gagné quoi ?
Posté par jmfayard . Évalué à 6.
[^] # La même solution en correct.
Posté par jmfayard . Évalué à 2.
[^] # Re: La même solution en correct.
Posté par Matthieu BENOIST . Évalué à 1.
pour le }{$_=$x' c'est juste pour sortir de la boucle du -p et initialiser $_ pour l'afficher ensuite (toujours le -p), bon, il manque il manque quelques points virgules aussi, mais on est pas à ça pret !
Vive le perl :) A noter que chez moi cet uniligne et presque aussi rapide qu'un du, mais semble plus précis :
par exemple, pour /usr le script ce termine 1 seconde apres et les résultats sont :
du : 2975040
perl : 3026770
[^] # Re: La même solution en correct.
Posté par jmfayard . Évalué à 1.
[usr]# time ls -lRa|perl -aple '/^total/?$x+=$F[1]:$x}{$_=$x'
2336176
real 2m5.491s
[usr]# time du -s
2214772 .
real 0m23.815s
Pour le plus précis, tu comptes plusieurs fois tous liens durs
[^] # Re: La même solution en correct.
Posté par Matthieu BENOIST . Évalué à 1.
sur ma bécane (XP1800+) le du est moins de 10 secondes plus rapide sur environs 30 Go de fichiers. bon, j'imagine que ton disque dur n'est vraiment pas une foudre de guerre...
j'est çà :
[/usr]$ time -p du
[...]
2975040 .
real 31.55
user 0.34
sys 2.60
[usr]$ time -p ls -lRa|perl -aple '/^total/?$x+=$F[1]:$x}{while($x>1024){$x/=1024}$_=$x'
real 19.38
user 2.93
sys 2.83
2.88655281066895
Mais en effet, pour des très grosse quantité, l'uniligne et plus longue en général)
Pour le plus précis, en effet, je risque de compter plusieurs fois les liens durs, et je ne l'ai pas pris en compte. pour rappel les liens dur dont tu parle sont les ./ ../ c'est ça ?
En effet, à cause du -a du ls, ils sont listés donc comtabilisés, mea culpa, il faut donc faire un ls -A pour ne plus les avoir.
Sinon, je ne voit pas d'autre liens dur (c'est plutôt rare, avec les liens symboliques...)
Bon, j'ai pas encore des résultats comme sur windows : 30Go occupé, 43 To de libres (sur un disque de 40 Go) ;)
[^] # Re: La même solution en correct.
Posté par Matthieu BENOIST . Évalué à 1.
et puis les résultats varie quand même grandement :
[mitsuaki]$ time -p ls -lRa|perl -aple '/^total/?$x+=$F[1]:$x}{while($x>1024){$x/=1024}$_=$x'
real 7.05
user 0.45
sys 0.62
1.19140148162842
[mitsuaki]$ time -p ls -lRA|perl -aple '/^total/?$x+=$F[1]:$x}{while($x>1024){$x/=1024}$_=$x'
real 1.49
user 0.43
sys 0.27
1.18892002105713
tient, j'ai mis le -a et le -A, y'a quand même une bonne différence, merci de la remarque :)
[^] # Re: La même solution en correct.
Posté par newbix . Évalué à 1.
Tout ces benchmarks sont en fait absolument pipo.
[^] # Re: La même solution en correct.
Posté par Matthieu BENOIST . Évalué à 1.
pour mes 1 s de différence, les deux étaient lancés en même temps, mais doit y en avoir un qui profite plus que l'autre...
ls -lRA est moins rapide que du. Je connais pas l'ordre, mais c'est sur.
Reste plus qu'à faire un "ls -lRA en perl et en uniligne. mmh. euh, finalement, non.
[^] # Re: J'ai gagné quoi ?
Posté par Matthieu BENOIST . Évalué à 1.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.