Semplice calcolatrice da riga di comando


19

Problema:

Ogni tanto ho bisogno di fare semplici aritmetiche in un ambiente a riga di comando. EG dato il seguente output:

Disk /dev/sdb: 256GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start   End     Size    File system     Name  Flags
 1      1049kB  106MB   105MB   fat32                 hidden, diag
 2      106MB   64.1GB  64.0GB  ext4
 3      64.1GB  192GB   128GB   ext4
 5      236GB   256GB   20.0GB  linux-swap(v1)

Qual è un modo semplice per calcolare sulla riga di comando la dimensione dello spazio non allocato tra la partizione 3 e 5?

Cosa ho già provato:

avanti Cristo

bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
236-192
44
quit

dove il grassetto sopra è tutta la roba che ho bisogno di digitare per fare una semplice 236-192come bc 1+1echiFile 1+1 is unavailable.

espr

expr 236 - 192

dove ho bisogno di digitare spazi prima e dopo l'operatore come expr 1+1solo echi 1+1.


3
Se avete intenzione di fare questo in modo interattivo, non è necessario digitare quitin bc; premendo ctrl-Dlo farà, come in qualsiasi programma interattivo.
marzo

2
dcè (IMO) molto superiore a bc.
William Pursell,

1
Penso che lo spazio non allocato tra ptn 3 e 5 dovrebbe essere 236 - 192 e non 236 - 128?
Trauma digitale

@DigitalTrauma buon occhio! (Era solo un esempio e nessuno lo notò!)
Fabby

1
@JanM. Sono quello che ha votato a favore .... ;-)
Fabby

Risposte:


33

Puoi ridurre notevolmente la quantità di verbosità implicata nell'uso di bc:

$ bc <<<"236-192"
44
$ bc <<<"1+1"
2

(supponendo che la tua shell lo supporti).

Se preferisci avere questo come funzione:

$ c() { printf "%s\n" "$*" | bc }
$ c 1+1
2

Conservare la cdefinizione nel file di avvio della shell preferito se si desidera renderlo sempre disponibile.


2
bc<RET>236-128<RET>quit<RET>è di 16 battute. bc<<<"236-128"<RET>è di 15 battute. Non è ciò che definirei "quantità di digitazione notevolmente ridotta" :-) Inoltre, è bcpossibile uscire con ^D, quindi la prima opzione è ridotta a 13 sequenze di tasti (contando ^Dcome due).
L. Levrel,

Giusto, si tratta più di verbosità ;-).
Stephen Kitt,

2
@ L.Levrel Con la funzione c 1+1è proprio quello che mi serviva! :-) (risposta aggiornata per renderlo più chiaro)
Fabby

E se si fa in virgola mobile: c 'scale = 2; 17/3 '(o meglio, hanno ridimensionato una variabile utilizzata all'interno della funzione' c () 'e definisci il suo valore ogni volta che devi avere n cifre decimali. Il valore predefinito è 0.)
Olivier Dulac

1
Piuttosto utilizzare bc -lnella definizione della funzione per renderlo più capace.
Isaac,

22

Conchiglia

Il calcolo più semplice nella CLI è la stessa CLI (shell) (se IFSè l'impostazione predefinita):

$ echo $(( 22 + 333 ))
355

Gli spazi potrebbero essere omessi:

$ echo $((22*333))
7326

Poiché fa parte di POSIX, quasi tutte le shell ce l'hanno. E include la maggior parte delle funzionalità matematiche del linguaggio C (tranne che zsh ha una precedenza diversa, imposta C_PRECEDENCES per ripristinarlo su un valore compatibile):

$ echo $((22*333^2))
7324

E alcune shell hanno la maggior parte della sintassi matematica del linguaggio C (inclusa la virgola):

$ echo $((a=22,b=333,c=a*b,c))
7326

Ma è solo matematica intera (e di solito meno di 2 63 nei sistemi operativi attuali) in alcune shell:

$ echo $((1234/3))
411

$ zsh -c 'echo $((2**63))'
-9223372036854775808

Alcune shell potrebbero fare matematica mobile:

$ ksh -c 'echo $((1234/3.0))'
411.333333333333333

$ ksh -c 'echo $((12345678901234567890123/3.0))'
4.11522630041152263e+21

Evita zsh (zcalc ha problemi simili):

$ zsh -c 'echo $((12345678901234567890123 + 1))'
zsh:1: number truncated after 22 digits: 12345678901234567890123 + 1
-1363962815083169259

Ti consiglio di evitare expr, a volte ha bisogno di strane fughe:

$ expr 22 \* 333
7326

avanti Cristo

Al livello successivo è ( anche POSIX ) bc(cugino di RPN dc)

$ echo '22*333' | bc
7326

$ echo '22 333 * p' | dc
7326

L' dc era POSIX ma ha rimosso nel 2017 .

Più breve se la tua shell lo supporta:

$ bc <<<'22*333'
7326

O anche:

$ <<<'22*333' bc
7326

Entrambi sono calcolatori di precisione arbitrari con alcune funzioni matematiche interne:

$ bc <<<2^200
1606938044258990275541962092341162602522202993782792835301376

$ echo 's(3.1415/2)' | bc -l        # sine function
.99999999892691403749

awk

Dopo quegli strumenti di calcolo davvero di base , devi passare ad altre lingue

$ awk "BEGIN {print (22*33)/7}"
103.714

$ perl -E "say 22*33/7"
103.714285714286

$ python3 -c "print(22*33/7)"
103.71428571428571

$ php -r 'echo 22*33/7,"\n";'
103.71428571429

funzione

È possibile definire una funzione di una qualsiasi delle opzioni sopra:

c () 
{ 
    local in="$(echo " $*" | sed -e 's/\[/(/g' -e 's/\]/)/g')";
    gawk -M -v PREC=201 -M 'BEGIN {printf("%.60g\n",'"${in-0}"')}' < /dev/null
}

E usa:

$ c 22* 33 /7                   # spaces or not, it doesn't matter.
103.714285714285714285714285714285714285714285714285714285714

20

Leggendo i commenti di queste pagine , vedo un programma UNIX / Linux chiamato calcche fa esattamente quello che vuoi. Se su Debian / Ubuntu / derivati:

sudo apt-get install apcalc

allora puoi:

calc 236-192

e se aggiungi un alias alias c='calc'al tuo .bashrco /etc/bash.bashrcallora diventa semplicemente:

c 1+1

sulla riga di comando.


1
Non perfetto, ma abbastanza buono per un voto. Malinteso corretto in chat e downvote rimosso da un altro utente . Cancellata la mia (inferiore) risposta ... ;-)
Fabby


9

Il unitsprogramma, sebbene non sia destinato a essere utilizzato come una calcolatrice, in realtà funziona abbastanza bene come uno.

$ units "236-192"
    Definition: 44
$ 

Se ci sono spazi nell'espressione, allora l'espressione deve essere protetta da virgolette.
Supporta esponenziali e nidificazione profonda delle parentesi


3
È versatile: units -t -d 10 "236GB - 192GB" GBuscite 44, units -t -d 15 "236GB - 192GB" bytesuscite 44000000000, ecc.
agc

6

Come osservato in un commento a una risposta precedente, la shell standard (ba) sh consente di valutare le espressioni aritmetiche all'interno $((...)). Non ho potuto ricontrollare se fa parte dello standard POSIX, ma ho verificato che funzioni anche su Cygwin e sulla shell Mingw32.

Per vedere il risultato, dovresti davvero digitare echo $((...)), il che rende alcuni personaggi più di (uso interattivo di) bc. Tuttavia, per utilizzare il risultato in uno script, molto probabilmente questo sarà più breve della bcsoluzione (che potrebbe essere, ad esempio, `echo ...|bc`).

Per quanto riguarda la verbosità, il bccomando consente l'opzione -qche sopprime l'output del "normale bcbenvenuto GNU " .

Come osservazione finale, leggermente borderline, notiamo che bcnon è solo una calcolatrice ma piuttosto un linguaggio di programmazione completo (comprese le funzioni definite dall'utente, mentre e per i loop, ecc. Ecc.). Un altro fatto che suggerisce di preferire le capacità aritmetiche integrate per calcoli così semplici, piuttosto che un programma esterno. Ciò detto, l'estrazione dei dati per determinati numeri di partizione e la gestione dei suffissi "M", "G", come la domanda originale sembrava chiedere, potrebbero richiedere (g)awkpiuttosto che bc.

Fonti: https://www.gnu.org/software/bc/manual/html_mono/bc.html https://www.gnu.org/software/gawk/manual/html_node/Getting-Started.html


Grazie! Ottima prima risposta! +1
Fabby

2
$((...))si chiama Arithmetic Expansion ed è parte di POSIX: pubs.opengroup.org/onlinepubs/9699919799/utilities/… Per me il più grande svantaggio di questa funzionalità di una shell POSIX è che supporta solo l'aritmetica intera :(
pabouk

6

Quello che faccio in zsh è:

$ <<< $(( 236 - 192 ))
44

In bash, dovrei menzionare esplicitamente cat:

$ cat <<< $(( 236 - 192 ))
44

Se volessi che il risultato includesse cifre frazionarie (funziona in zsh, non in bash), aggiungerei un punto radix a uno degli operandi

$ <<< $(( 236 / 128 )) 
1
$ <<< $(( 236. / 128 ))
1.84375

7
echo $((236 - 128))funziona anche ;-).
Stephen Kitt,

Evitare zsh: zsh -c 'print $((12345678901234567890123 + 1))' zsh:1: number truncated after 22 digits: 12345678901234567890123 + 1 -1363962815083169259.
Isaac,

@Isaac almeno zsh ti dice che sta troncando; bash ti dà solo una risposta errata senza lamentarti.
Stephen Kitt,

@StephenKitt Il problema con zsh è più complesso di quanto mostra un output. Confronta: zsh -c 'print $((12345678901234567890123 + 1))'e zsh -c 'print $((123456789012345678901 + 1))'. Si sta troncando a lunghezze diverse e producendo risultati numerici diversi.
Isaac,

@StephenKitt Invece Bash sta seguendo il manuale (e il linguaggio C sull'overflow di un int firmato). Non che mi piaccia personalmente, ma è documentato come tale. Prova bash -c 'echo $((1<<63))'e `` bash -c 'echo $ (((1 << 63) -1))' '.
Isaac,

6

Personalmente, mi piace libqalculate (la versione da riga di comando di Qalculate ).

$ qalc
> 236-192

  236 - 192 = 44

Sebbene l'interfaccia sia certamente semplice, (lib) qalculate è un potente calcolatore completo. per esempio

> fibonacci(133) to hex

  fibonacci(133) = approx. 0x90540BE2616C26F81F876B9

> 100!

  factorial(100) = approx. 9.3326215E157

> sin(pi)

  sin(pi * radian) = 0

Fa anche cose utili come il completamento della scheda, apri / chiudi parentesi quando necessario e stampa la sua interpretazione della query.

> 18-2)/4

  (18 - 2) / 4 = 4

Per uscire premo semplicemente Ctrl+ d.

Per un accesso ancora più veloce, impostalo su qualcosa di simile alias ca='qalc'.


Ho letto il sommario del manuale ma non sono riuscito a trovare nulla sulla CLI. (+1 nel frattempo)
Fabby,

1
Grazie @Fabby. Mi sono confuso e la parte della CLI è in realtà leggermente diversa. Ho aggiornato la risposta per chiarire.
Sparhawk,

Vorrei poterti votare due volte! ;-)
Fabby,

4

Python si apre in un'altra scheda?

Python 3.6.3 (v3.6.3:2c5fed8, Oct  3 2017, 17:26:49) [MSC v.1900 32 bit (Intel)] on 
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> 3+3
6
>>>

No, non proprio, ma un'idea chiara comunque! :-) +1
Fabby

PowerShell può anche fare la stessa cosa
phuclv,

1
@phuclv sì, ma a nessuno piace PS
Dev

3
@Dev tonnellate di persone Unix adorano PS
phuclv,

2

dc -e '236 192-p'

... ovviamente, se non hai familiarità dce hai bisogno di qualcosa di più che sottrarre due numeri, passerai più tempo a cercare come usare dc(e forse RPN in generale) di quanto risparmierai con metodi più familiari.


Sì, ho dato un'occhiata a Desk Calculator per 3 minuti e sapevo che non era per me: ero un TI, non uno studente HP.
Fabby,

2

Se hai installato Gradle, allora hai Groovy ...

Se groovy è percorso correttamente dovresti essere in grado di usare:

groovy -e "println 1+1"

Questo può sembrare un po 'ridondante con tutti gli altri esempi, ma:

  • groovy è un linguaggio potente
  • probabilmente il miglior supporto di libreria disponibile
  • funzioni matematiche potenti e semplici (come la matematica di precisione arbitraria)
  • utilizza stdout reindirizzabile per il suo output, quindi è incredibilmente flessibile (ottimo da usare all'interno di file batch con backtick `` e simili).

Se non hai installato java, probabilmente non vale la pena installare groovy e java - è solo un'opzione se groovy è già disponibile.


No, non proprio, ma un'idea chiara comunque! :-) +1
Fabby

2

Hai provato concalc ?

Descrizione: calcolatrice console concalc è una calcolatrice per la console Linux. È solo l'algoritmo parser di extcalc racchiuso in un semplice programma console. Puoi usarlo se hai bisogno di una calcolatrice nella tua shell. concalc è anche in grado di eseguire script scritti in un linguaggio di programmazione simil-C.

$ concalc 1+1
2
$ concalc sqrt2
1.41421356237309505

Installa con:

sudo apt-get install concalc

1
a prova ... Graag gedaan ... :-D
Fabby

2

Prima che fosse pubblicata una delle altre brillanti risposte, ho finito per creare lo script /usr/local/bin/ccontenente:

#!/bin/sh
IFS=' '               # to be on the safe side, some shells fail to reset IFS.
if [ "$#" -eq 0 ];  then
    echo "$(basename "$0"): a (very) simple calculator."
    echo "type $(basename "$0") expression to evaluate (uses bc internally)"
fi

printf '%s\n' "$*" | bc -l  # safe for most shells
                            # we may use 'bc -l <<<"$*"` for ksh, bash, zsh

quindi: scrivere i c 1+1rendimenti 2! :-)

Nota 1: l' ho usato cperché quel comando non esiste su nessun sistema Unix che sono riuscito a trovare. Se lo avessi assegnato al tuo compilatore c, usa qualcos'altro di breve e non lo usi.
Nota 2: fonte


1
(1) Ho deciso di usare echo "$*" | bc -lcome lo shebang che hai usato era /bin/she non so se hai ksh / bash / zsh disponibile. (2) Nota che puoi cambiare la scala da calcolare se esegui `c 'scale = 60; 777/333', per esempio. Spero che aiuti @Fabby
Isaac il

1

Se è installato Python, è possibile eseguire molte operazioni matematiche tramite la riga di comando. Ho provato a fornire alcuni esempi di seguito.

Ho usato python3che puoi usare python. La differenza tra pythone si python3verifica quando si verifica un'operazione divisa (frazionaria), per evitare il problema vedere di seguito python vs python3 .

Nota: la versione più recente di tutte le dist linux viene fornita con Python 2.7 e Python 3.5 per impostazione predefinita. Nel caso in cui sia necessario installare Python, fare clic qui .

Aggiungi, Sottrai, Moltiplica e Dividi:

$ python3 <<< "print(12+3)"
15
$ python3 <<< "print(12-3)"
9
$ python3 <<< "print(12*3)"
36
$ python3 <<< "print(12/3)"
4

Modulo-resto della divisione:

$ python3 <<< "print(14%3)"
2

Divisione piano:

$ python3 <<< "print(14//3)"
4

Esponente - x alla potenza di y (x ^ y):

$ python3 <<< "print(3**2)"
9

Radice quadrata (es: √4 = 2):

$ python3 <<< "print(4**0.5)"
2

Parte più scientifica, avrai bisogno di matematica di importazione libreria . Ex:

Il logaritmo naturale di x = log (x):

$ python3 <<< "import math; print(math.log(4))"
1.386294361119890e6

Il logaritmo in base 10 di x = log10 (x):

$ python3 <<< "import math; print(math.log10(10))"
1.0

Fattoriale (es: 3! = 3.2.1 = 6):

$ python3 <<< "import math; print(math.factorial(3))"
6

Trigonometry- sin(x), cos(x), tan(x):

$ python3 <<< "import math; print(math.sin(90))"
0.8939966636005579

Per ulteriori funzioni matematiche, consultare qui .

pythonVs python3:

-Per dividere: (usare float):

$ python <<< "print(10.0/3)"
3.33333333333

-invece di

$ python <<< "print(10/3)"
3

Inoltre è possibile utilizzare il terminale diretto:

$ python3
Python 3.6.8 (default, Jan 14 2019, 11:02:34) 
[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 1+3
4
>>> import math
>>> math.log10(4)
0.6020599913279624
>>> math.sqrt(4)
2.0
>>> 

Questo è tutto. Buona programmazione!


0

O bcoppure qalc.


Per avere automaticamente un bcarrotondamento sempre a due cifre: (eseguirlo con -lè ingombrante per roba di tutti i giorni)

Modifica il tuo ~/.bashrc:

alias bc="BC_ENV_ARGS=<(echo "scale=2") \bc"

Apri una nuova shell ed esegui bclì.


-1

Creare un one-liner:

$ c () { echo $(( ${1} )) }

Ora puoi usare la matematica intera semplice:

$ c 1+1
2

$ c 25*4
100

$ c 25*4-10
90

$ c 20*5/4
25

Questo è già discusso nella risposta di Isaac .
Stephen Kitt,

@StephenKitt Sì, ho valutato la risposta molto dettagliata di Isaac. Ho pensato che sarebbe stato utile un solo riassunto che riassumesse alcuni dei suoi post. L' ${1}utilizzo dei parametri è unico per tutte le risposte.
WinEunuuchs2Unix

2
Ti incoraggio a esaminare i motivi per cui le altre risposte non usano ${1};-)
Stephen Kitt il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.