Plus de détails sur comment gérer une playlist pour le nouvel an

Auteurice : Arthur Pons

Temps de lecture : ~2 minutes


t2s2t

C’est super nul comme nom. Sinon voici le code :

#! /bin/sh

if [ ! "$1" = "-r" ]
then
    sed 's/:/*3600+/;s/:/*60+/' | bc -l
else
    xargs printf 'tot=%s;
                  hours=tot/3600;
                  minutes=(tot-3600*hours)/60;
                  seconds=tot-3600*hours-60*minutes;
                  print hours,":",minutes,":",seconds,"\n";
                  \n' |
    bc |
    sed -E 's/^[0-9]:/0&/;
            s/:([0-9]):/:0\1:/;
            s/:([0-9])$/:0\1/'
fi

En gros si le script est utilisé dans le sens hh:mm:ss -> ssss alors on remplace simplement le premier : par *3600+ et le second par *60+. Ainsi pour 01:23:55 on obtient l’expression mathématique 01*3600+23*60+55 que l’on donne à bc et hop le tour est joué.

Si le script est utilisé dans l’autre sens le problème est un peu plus compliqué. Les commandes bc (après le printf) fonctionnent parce qu’appeler bc sans l’option -l empêche les opérations sur des flottants et arrondi donc tout à l’entier inférieur. Ainsi 3654/3600 donne 1, c’est à dire le nombre d’heures dans 3654 secondes. On soustrait ensuite le nombre d’heures complètes au total pour le diviser par 60 pour avoir le nombre de minutes complètes au delà du nombre d’heures complètes. (3654-3600*1)/60 donne 54/60 qui donne 0 puis de même avec les secondes qui ici va donner 54. Finalement on affiche les trois variables séparées avec des :. Afin de pouvoir manger une potentielle longue liste de valeur on utilise xargs et printf.

Admettons que l’on a la liste suivante :

seq 200 205

200
201
202
203
204
205

Notre commande xargs va générer la commande printf suivante : printf ‘tot=%s; hours=tot/3600; minutes=(tot-3600hours)/60; seconds=tot-3600hours-60*minutes; print hours,”:”,minutes,”:”,seconds,”\n”;’ 200 201 202 203 204 205

Qui déroulée va donner

tot=200;
hours=tot/3600;
minutes=(tot-3600*hours)/60;
seconds=tot-3600*hours-60*minutes;
print hours,":",minutes,":",seconds,"\n";

puis pareil avec 201 etc. On met tout dans bc puis on passe un coup de sed pour ajouter des 0 quand il en manque.

cumulduration

Le code est celui-ci :

#! /bin/sh

tot=0
for duration in $(cat)
do
    tot=$(( tot + $duration ))
    echo $tot
done

On boucle sur chaque ligne dans STDIN. Pour chacune d’entre elle on ajoute la valeur lue au total et on affiche sa valeur courante. Simple efficace.

predict

Le code :

#!/bin/sh

echo "0\n$(cat)" |
    xargs printf "$(date -Iseconds --date "$1")+%sseconds\n" |
    date -f - +"%X"

On ajoute un 0 en début de flux sinon le résultat nous dira que la première chanson se lance après sa propre durée. Il faut donc lui faire croire qu’il existe une première de durée nulle. On construit une commande printf avec en argument toutes les durées en seconde de façon à construire tous les formats de date. Notez le $1 qui permet de passer le date de début en argument à predict. Par exemple pour une date de début au 31 décembre à 19h :

seq 200 210 | 
        xargs printf "$(date -Iseconds --date "dec 31 19:00")+%sseconds\n"

Lancera la commande

printf "2023-12-31T19:00:00+01:00+%sseconds\n" 200 201 202 203 204 205 206 207 208 209 210

qui donne :

2023-12-31T19:00:00+01:00+200seconds
2023-12-31T19:00:00+01:00+201seconds
2023-12-31T19:00:00+01:00+202seconds
2023-12-31T19:00:00+01:00+203seconds
2023-12-31T19:00:00+01:00+204seconds
2023-12-31T19:00:00+01:00+205seconds
2023-12-31T19:00:00+01:00+206seconds
2023-12-31T19:00:00+01:00+207seconds
2023-12-31T19:00:00+01:00+208seconds
2023-12-31T19:00:00+01:00+209seconds
2023-12-31T19:00:00+01:00+210seconds

formats qui mangés par date en demandant de n’afficher que l’heure donnent :

printf "2023-12-31T19:00:00+01:00+%sseconds\n" 200 201 202 203 204 205 206 207 208 209 210 |
    date -f - +"%X"

19:03:20
19:03:21
19:03:22
19:03:23
19:03:24
19:03:25
19:03:26
19:03:27
19:03:28
19:03:29
19:03:30

En tout 24 lignes de code.