Come posso ottenere bc (1) per stampare lo zero iniziale?

Faccio qualcosa di simile al seguente in un Makefile:

echo "0.1 + 0.1" | bc 

(nel file reale i numeri sono dinamici, ovviamente)

Stampa .2 ma voglio che stampi 0.2 .

Mi piacerebbe farlo senza ricorrere a sed ma non riesco a trovare come ottenere bc per stampare lo zero. O semplicemente non è in grado di farlo?

Puoi anche ricorrere a awk per formattare:

  echo "0.1 + 0.1" | bc | awk '{printf "%f", $0}' 

o con awk stesso a fare i conti:

  echo "0.1 0.1" | awk '{printf "%f", $1 + $2}' 

Questo potrebbe funzionare per te:

 echo "x=0.1 + 0.1; if(x<1) print 0; x" | bc 

Dopo una rapida occhiata al sorgente (vedi bc_out_num() , riga 1461), non vedo un modo ovvio per far stampare lo 0 se la parte intera è 0 . A meno che non mi sia sfuggito qualcosa, questo comportamento non dipende da un parametro che può essere modificato utilizzando il flag della riga di comando.

Risposta breve: no, non penso che ci sia un modo per fare i numeri di stampa in bc nel modo che preferisci.

Non vedo nulla di sbagliato nell’usare sed se si desidera ancora utilizzare bc . Quello che segue non sembra così orribile, IMHO:

 [[email protected]]$ echo "0.1 + 0.1" | bc | sed 's/^\./0./' 0.2 

Se vuoi davvero evitare di sedare , i suggerimenti di eljunior e di choroba sono abbastanza accurati, ma richiedono un aggiustamento del valore per evitare gli zero finali. Questo potrebbe o non potrebbe essere un problema per te.

Non riesco a trovare nulla sul formato di output nella documentazione. Invece di sed, puoi anche raggiungere printf:

 printf '%3.1f\n' $(bc<<<0.1+0.1) 
 $ 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' 

Questo è puro bc . Rileva lo zero iniziale confrontando il risultato della length con la scale dell'espressione. Funziona sia con numeri positivi che negativi.

Questo gestirà anche i numeri negativi:

 echo "0.1 - 0.3" | bc | sed -r 's/^(-?)\./\10./' 

questo usa solo bc e funziona con numeri negativi:

 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"; 

provalo con:

 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 

Probabilmente, bc non è davvero il miglior “calcolatore da banco” per l’età moderna. Altre lingue ti daranno più controllo. Ecco alcuni esempi di lavoro che stampano valori nell’intervallo (-1.0 .. + 1.0) con uno zero iniziale. Questi esempi usano bc , AWK e 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)") } 

Si noti che la versione di Python è circa 10 volte più lenta, se questo è importante.

Per i numeri positivi, potrebbe essere semplice come stampare (una stringa) zero:

 $ echo '"0";0.1+0.1' | bc 0.2 

evitare lo zero se il numero è maggiore (o uguale) a 1:

 $ echo 'x=0.1+0.1; if(x<1){"0"}; x' | bc 0.2 

Diventa un po 'più complesso se il numero può essere negativo:

 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 

È ansible definire una funzione e aggiungerla a una libreria:

 $ 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 

Basandosi sulla risposta dei vasi,

Per risultati frazionari:

 echo "x=0.1 + 0.1; if(x<1 && x > 0) print 0; x" | bc -l 

Si noti che i risultati negativi non verranno visualizzati correttamente. Aquarius Power ha una soluzione per questo.

echo "$a / $b" | bc -l | sed -e 's/^-\./-0./' -e 's/^\./0./'

Questo dovrebbe funzionare per tutti i casi in cui i risultati sono:

  • “-.123”
  • ” .123″
  • “-1.23”
  • “1.23”

Spiegazione:

  1. Per tutto ciò che inizia solo con -. , sostituire -. con -0.

  2. Per tutto ciò che inizia solo con . , sostituire . con 0.