Histogramme et ligne de commande

Un petit utilitaire.

J’ai reprogrammé en php un clone de spark.

Un petit exemple est plus parlant

1
2
spark([1,2,3,4,4,5,6,1,2]); // ▂▃▅▆▆▇█▂▃
spark([1,2,3,4,5,1,2,3,4,5]); //▂▄▅▇█▂▄▅▇█

Voici l’implémentation

1
2
3
4
5
6
7
8
9
10
11
12
function spark($array) {
    $bars = array('▁','▂','▃','▄','▅','▆','▇','█');
    $divide = max($array);
    if ($divide == 0) {
        $divide = 1;
    }
    $countBars = count($bars)-1;
    $out = '';
    foreach ($array as $tick)
        $out .= $bars[round(($tick / $divide) * $countBars)];
    echo $out;
}

L’appeler en ligne de commande.

La documentation de spark donne cette ligne de commande

1
spark 0 30 55 80 33 150

Est ce qu’on peux faire la même chose ? Il suffit de rajouter les deux lignes suivantes.

1
2
3
$iDontCare =array_shift($argv);
spark($argv);
return 0;

On utilise la variable $argv qui est le tableau de paramètres passer dans la ligne de commande. L’argument $argv[0]est le nom du programme, c’est pour cela que l’on fait un array_shift cela supprime la première valeur du tableau.

1
2
php spark.php 0 30 55 80 33 150
▁▂▄▅▃█

L’appeler via les pipes

Un peu plus compliqué via les pipes du Shell.

Les implémentations des Pipes se présentent toujours un peu de la même manière. On utilise STDIN qui représente l’entrée standard.

Un exemple qui traduit les caractères accentués. é->&eacute

1
2
3
4
5
#!/usr/bin/env php
<?php
while (!feof(STDIN)) {
     echo htmlentities(fgets(STDIN));
}

La ligne !/usr/bin/env php s’appelle le shebang

Puis rendre exécutable le fichier

1
chmod +x htmlentities.php

Des exemples

1
2
3
4
5
$ echo 'énergie' | ./htmlentities.php

&eacute;nergie

$ cat file.txt | ./htmlentities

Ce qui est cool c’est que l’on peux chainer les opérateur.

Un programme qui passe la première lettre en majuscule.

1
2
3
4
5
#!/usr/bin/env php
<?php
while (!feof(STDIN)) {
     echo ucfirst(trim(fgets(STDIN)));
}

Un programme qui aime crier !!!!.

1
2
3
4
5
#!/usr/bin/env php
<?php
while (!feof(STDIN)) {
     echo trim(fgets(STDIN)).'!!!!';
}
1
2
$ echo 'récuperation' | ./shoot.php | ./capitalize.php | ./htmlentities.php
R&eacute;cup&eacute;ration!!!!

C’est un peu plus compliqué dans la vrai vie avec les retours à la ligne vide. Mais j’espère que vous avez compris mon idée.

Retour à notre script.

Voici la partie pour récupérer de la ligne de commande.

1
2
3
4
5
6
7
8
9
10
11
12
// si je n'ai aucun argument ..
if (count($argv) == 0) {
    $str = '';
    // recupère le flux d'entrée
    while (!feof(STDIN)) {
        $str .= fgets(STDIN);
    }
    // explode laisse la derniere ligne vide.
    // d'ou le array_filter
    spark(array_filter(explode("\n", $str),'strlen'));
    return 0;
}

Essayons une commande sur le dépôt git du blog que vous lisez.

1
git shortlog -s | cut -f1 | php ~/prog/spark/spark.php
1
2
3
4
5
6
$ git shortlog -s
(...)
   2  Manu
   37  Marc Camuzat
   1  Marcus Young
(..)

On ne garde que la colonne 1 avec cut -f1 puis on passe au script php

On obtient

1
▁▁▁▁▁▁▁▁▁▁▁▁▃▁▁▁▁▁▁█▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▃▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁

Conclusion

J’avais besoin pour un futur article (le prochain ?) de cette fonction. La philosophie de Linux est de créer plein de petits programmes et que ceux-ci communiquent via une interface très simple et universelle qui est le fichier texte. Ainsi il n’y a aucune dépendance le programme 1 est en bash, le programme 2 est en C, le programme 3 est en PHP. Et tout cela ne pose aucun problème.