Je fais quelque chose comme ce qui suit dans un Makefile:
echo "0.1 + 0.1" | bc
(dans le vrai fichier les nombres sont dynamiques, bien sûr)
Il imprime .2
mais je veux qu’il imprime 0.2
.
Je voudrais faire ceci sans recourir à sed
mais je n'arrive pas à trouver comment obtenir bc
pour imprimer le zéro. Ou bc
n'est-il simplement pas capable de faire cela?
Vous pouvez également recourir à awk pour formater:
echo "0.1 + 0.1" | bc | awk '{printf "%f", $0}'
ou avec awk elle-même faisant le calcul:
echo "0.1 0.1" | awk '{printf "%f", $1 + $2}'
Cela pourrait fonctionner pour vous:
echo "x=0.1 + 0.1; if(x<1) print 0; x" | bc
Après un coup d’œil rapide sur la source (voir bc_out_num()
, ligne 1461), je ne vois pas de moyen évident d’imprimer le 0
qui précède soit imprimé si la partie entière est 0
. À moins que quelque chose ne m'ait échappé, ce comportement ne dépend pas d'un paramètre qui peut être modifié à l'aide d'un indicateur de ligne de commande.
Réponse courte: non, je ne pense pas qu'il soit possible de faire imprimer des numéros bc
comme vous le souhaitez.
Je ne vois aucun inconvénient à utiliser sed
si vous souhaitez toujours utiliser bc
. Ce qui suit ne semble pas si affreux, à mon humble avis:
[me@home]$ echo "0.1 + 0.1" | bc | sed 's/^\./0./'
0.2
Si vous voulez vraiment éviter sed
, les deux suggestions de eljunior et choroba sont plutôt soignées, mais elles nécessitent un ajustement dépendant de la valeur pour éviter les zéros. Cela peut ou peut ne pas être un problème pour vous.
Je ne trouve rien sur le format de sortie dans la documentation. Au lieu de sed, vous pouvez également accéder à printf:
printf '%3.1f\n' $(bc<<<0.1+0.1)
Celui-ci traitera également les nombres négatifs:
echo "0.1 - 0.3" | bc | sed -r 's/^(-?)\./\10./'
$ bc -l <<< 'x=-1/2; if (length (x) == scale (x) && x != 0) { if (x < 0) print "-",0,-x else print 0,x } else print x'
Celui-ci est pur bc
. Il détecte le zéro initial en comparant le résultat de length
avec scale
de l'expression. Cela fonctionne sur les nombres positifs et négatifs.
Pour les nombres positifs, cela peut être aussi simple que d’imprimer (une chaîne) zéro:
$ echo '"0";0.1+0.1' | bc
0.2
éviter le zéro si le nombre est plus grand (ou égal) à 1:
$ echo 'x=0.1+0.1; if(x<1){"0"}; x' | bc
0.2
Cela devient un peu plus complexe si le nombre peut être négatif:
echo 'x= 0.3 - 0.5 ; s=1;if(x<0){s=-1};x*=s;if(s<0){"-"};if(x<1) {"0"};x' | bc
-0.2
Vous pouvez définir une fonction et l'ajouter à une bibliothèque:
$ echo 'define leadzero(x){auto s;
s=1;if(x<0){s=-1};x*=s;if(s<0){"-"};if(x<1){"0"};
return(x)};
leadzero(2.1-12.4)' | bc
-10.3
$ echo 'define leadzero(x){auto s;
s=1;if(x<0){s=-1};x*=s;if(s<0){"-"};if(x<1){"0"};
return(x)};
leadzero(0.1-0.4)' | bc
-0.3
echo "$a / $b" | bc -l | sed -e 's/^-\./-0./' -e 's/^\./0./'
Cela devrait fonctionner dans tous les cas où les résultats sont:
Explication:
Pour tout ce qui ne commence que par -.
, remplacez -.
par -0.
Pour tout ce qui ne commence que par .
, remplacez .
par 0.
bc
n'est probablement pas le meilleur "calculateur de banc" du monde moderne. D'autres langues vous donneront plus de contrôle. Voici des exemples de travail qui affichent des valeurs dans la plage (-1.0 .. + 1.0) avec un zéro non significatif. Ces exemples utilisent bc
, AWK
et Python 3
.
#!/bin/bash
echo "using bc"
time for (( i=-2; i<=+2; i++ ))
{
echo $(bc<<<"scale=1; x=$i/2; if (x==0||x<=-1||x>=1) { print x } else { if (x<0) { print \"-0\";-x } else { print \"0\";x } } ")
}
echo
echo "using awk"
time for (( i=-2; i<=+2; i++ ))
{
echo $(echo|awk "{printf \"%.1f\",$i/2}")
}
echo
echo "using Python"
time for (( i=-2; i<=+2; i++ ))
{
echo $(python3<<<"print($i/2)")
}
Notez que la version Python est environ 10 fois plus lente, si cela compte.
cela utilise uniquement bc et fonctionne avec des nombres négatifs:
bc <<< "x=-.1; if(x==0) print \"0.0\" else if(x>0 && x<1) print 0,x else if(x>-1 && x<0) print \"-0\",-x else print x";
essayez-le avec:
for y in "0" "0.1" "-0.1" "1.1" "-1.1"; do
bc <<< "x=$y; if(x==0) print \"0.0\" else if(x>0 && x<1) print 0,x else if(x>-1 && x<0) print \"-0\",-x else print x";
echo;
done