Calculadora simples de linha de comando

19

Questão:

De vez em quando, preciso fazer aritmética simples em um ambiente de linha de comando. EG dada a seguinte saída:

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 é uma maneira simples de calcular na linha de comando o tamanho do espaço não alocado entre as partições 3 e 5?

O que eu já tentei:

bc

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

onde o negrito acima é tudo o que eu preciso digitar para fazer um simples 236-192como bc 1+1ecosFile 1+1 is unavailable.

expr

expr 236 - 192

onde eu preciso digitar espaços antes e depois do operador expr 1+1apenas como ecos 1+1.

Fabby
fonte
3
Se você está pretendendo fazer isso de forma interativa, você não precisa digitar quitem bc; pressionar ctrl-Dfará, como acontece em qualquer programa interativo.
Marcelm #
2
dcé (IMO) muito superior a bc.
William Pursell
11
Eu acho que o espaço não alocado entre ptn 3 e 5 deve ser 236 - 192, e não 236 - 128?
Digital Trauma
@DigitalTrauma good eye! (Foi apenas um exemplo e ninguém percebeu que um!)
Fabby
11
@JanM. Eu sou o único que votou .... ;-)
Fabby

Respostas:

33

Você pode reduzir bastante a quantidade de verbosidade envolvida no uso de bc:

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

(supondo que seu shell suporte isso).

Se você preferir ter isso como uma função:

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

Armazene a cdefinição no seu arquivo de inicialização do shell favorito, se desejar torná-la sempre disponível.

Stephen Kitt
fonte
2
bc<RET>236-128<RET>quit<RET>é de 16 teclas. bc<<<"236-128"<RET>é de 15 teclas. Não é o que eu chamaria de "quantidade bastante reduzida de digitação" :-) Além disso, bcpode ser encerrada com ^D, portanto, a primeira opção é reduzida para 13 pressionamentos de tecla (contando ^Dcomo dois).
L. Levrel
Certo, é mais sobre verbosidade ;-).
Stephen Kitt
2
@ L.Levrel Com a função, c 1+1é exatamente o que eu precisava! :-) (resposta atualizada para fazer com que mais clara)
Fabby
E se você fizer ponto flutuante: c 'scale = 2; 17/3 '(ou melhor, dimensione uma variável usada dentro da função' c () 'e defina seu valor sempre que você precisar ter n dígitos decimais. O padrão é 0.)
Olivier Dulac
11
Em vez disso, use bc -lna definição da função para torná-la mais capaz.
Isaac
22

Concha

O cálculo mais simples na CLI é a própria CLI (shell) (se IFSfor o padrão):

$ echo $(( 22 + 333 ))
355

Os espaços podem ser omitidos:

$ echo $((22*333))
7326

Como faz parte do POSIX, quase todas as conchas o possuem. E inclui a maior parte da funcionalidade matemática da linguagem C (exceto que o zsh tem uma precedência diferente, defina C_PRECEDENCES para restaurá-lo para um valor compatível):

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

E alguns shells possuem a maior parte da sintaxe matemática da linguagem C (incluindo vírgula):

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

Mas é apenas matemática inteira (e geralmente menor que 2 63 nos sistemas operacionais atuais) em algumas conchas:

$ echo $((1234/3))
411

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

Algumas conchas podem fazer cálculos flutuantes:

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

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

Evite o zsh (o zcalc tem problemas semelhantes):

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

Eu recomendo que você evite expr, às vezes precisa de escapamentos estranhos:

$ expr 22 \* 333
7326

bc

No próximo nível é ( também POSIX ) bc(primo da RPN dc)

$ echo '22*333' | bc
7326

$ echo '22 333 * p' | dc
7326

A dc era POSIX mas foi removido em 2017 .

Mais curto se o seu shell o suportar:

$ bc <<<'22*333'
7326

Ou até:

$ <<<'22*333' bc
7326

Ambos são calculadoras de precisão arbitrárias com algumas funções matemáticas internas:

$ bc <<<2^200
1606938044258990275541962092341162602522202993782792835301376

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

awk

Depois dessas ferramentas básicas de cálculo, você precisa ir para outros idiomas

$ 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

função

Você pode definir uma função de qualquer uma das opções acima:

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 use:

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

Lendo os comentários desta página , vejo um programa UNIX / Linux chamado calcque faz exatamente o que você deseja. Se estiver no Debian / Ubuntu / derivados:

sudo apt-get install apcalc

então você pode:

calc 236-192

e se você adicionar um alias alias c='calc'ao seu .bashrcou /etc/bash.bashrcentão ele se tornará:

c 1+1

na linha de comando.

número 9
fonte
11
Não é perfeito, mas é bom o suficiente para uma votação. Incompreensão corrigida no bate-papo e voto negativo removido por outro usuário . Excluída a minha própria resposta (inferior) ... ;-)
Fabby
15

Em zsh:

$ autoload zcalc # best in  ~/.zshrc
$ zcalc
1> 1+1
2
2> ^D
$ zcalc 5+5
1> 10
2>
Stéphane Chazelas
fonte
9

O unitsprograma, embora não se destine a ser usado como calculadora, na verdade funciona bastante bem como um.

$ units "236-192"
    Definition: 44
$ 

Se houver espaços na expressão, ela deverá estar protegida por aspas.
Suporta exponenciais e aninhamento profundo de colchetes

CSM
fonte
3
É versátil: units -t -d 10 "236GB - 192GB" GBsaídas 44, units -t -d 15 "236GB - 192GB" bytessaídas 44000000000, etc.
AGC
6

Conforme comentado em um comentário a uma resposta anterior, o shell padrão (ba) sh permite avaliar expressões aritméticas em $((...)) . Não pude verificar se isso faz parte do padrão POSIX, mas verifiquei se ele também funciona no Cygwin e no shell Mingw32.

Para ver o resultado, você precisaria digitar echo $((...)), o que torna alguns caracteres mais do que (uso interativo de) bc. No entanto, para usar o resultado em um script, provavelmente será mais curto que a bcsolução (que pode ser, por exemplo,`echo ...|bc` ).

No que diz respeito à verbosidade, o bccomando permite a opção -qque suprime a saída do " bcbem-vindo normal ao GNU " .

Como uma observação final, levemente limítrofe, observe que bcnão é apenas uma calculadora, mas uma linguagem de programação completa (incluindo funções definidas pelo usuário, while & for loops, etc etc). Outro fato que sugere preferir os recursos aritméticos integrados para cálculos tão simples, em vez de um programa externo. Dito isso, extrair os dados para o (s) número (s) de partição e lidar com os sufixos "M", "G", como parecia a pergunta original, poderia exigir (g)awkmais do que bc.

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

Máx.
fonte
Obrigado! Excelente primeira resposta! 1
Fabby
2
$((...))é chamado de expansão aritmética e faz parte do POSIX: pubs.opengroup.org/onlinepubs/9699919799/utilities/… Para mim, a maior desvantagem desse recurso de um shell POSIX é que ele suporta apenas aritmética inteira :(
pabouk
6

O que faço no zsh é:

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

No bash, eu teria que mencionar explicitamente cat:

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

Se eu quisesse que o resultado incluísse dígitos fracionários (funciona no zsh, não no bash), adicionaria um ponto de raiz a um dos operandos

$ <<< $(( 236 / 128 )) 
1
$ <<< $(( 236. / 128 ))
1.84375
JoL
fonte
7
echo $((236 - 128))funciona também ;-).
Stephen Kitt
Evite zsh: zsh -c 'print $((12345678901234567890123 + 1))' zsh:1: number truncated after 22 digits: 12345678901234567890123 + 1 -1363962815083169259.
Isaac Isaac
@ Isaac pelo menos zsh diz que é truncado; bash apenas fornece uma resposta incorreta sem reclamar.
Stephen Kitt
@StephenKitt O problema com o zsh é mais complexo do que mostra uma saída. Compare: zsh -c 'print $((12345678901234567890123 + 1))'e zsh -c 'print $((123456789012345678901 + 1))'. É truncado em diferentes comprimentos e produzindo resultados numéricos diferentes.
Isaac Isaac
@StephenKitt Em vez disso, o Bash segue o manual (e o idioma C sobre o estouro de um int assinado). Não que eu pessoalmente goste, mas está documentado como tal. Tente bash -c 'echo $((1<<63))'e `` bash -c 'echo $ (((1 << 63) -1))' '.
Isaac Isaac
6

Pessoalmente, gosto da libqalculate (a versão da linha de comandos do Qalculate ).

$ qalc
> 236-192

  236 - 192 = 44

Embora a interface seja certamente simples, (lib) qalculate é uma calculadora poderosa e completa. por exemplo

> fibonacci(133) to hex

  fibonacci(133) = approx. 0x90540BE2616C26F81F876B9

> 100!

  factorial(100) = approx. 9.3326215E157

> sin(pi)

  sin(pi * radian) = 0

Ele também faz coisas úteis como o preenchimento de guias, abre / fecha parênteses quando necessário e imprime sua interpretação da consulta.

> 18-2)/4

  (18 - 2) / 4 = 4

Para sair, basta pressionar Ctrl+d .

Para um acesso ainda mais rápido, defina-o para algo como alias ca='qalc'.

Sparhawk
fonte
Eu li o sumário do manual, mas não consegui encontrar nada sobre a CLI. (+1 entretanto)
Fabby
11
Obrigado @Fabby. Fiquei confuso, e a parte CLI é realmente um pouco diferente. Atualizei a resposta para esclarecer.
Sparhawk
Eu gostaria de poder te votar duas vezes! ;-)
Fabby
4

Python aberto em outra guia?

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
>>>
Michael Hearn
fonte
Não, na verdade não, mas uma boa idéia de qualquer maneira! :-) +1
Fabby
PowerShell também pode fazer a mesma coisa
phuclv
11
@phuclv sim, mas ninguém gosta PS
Dev
3
@Dev milhares de pessoas Unix amo PS
phuclv
2

dc -e '236 192-p'

... é claro, se você não estiver familiarizado dce precisar mais do que subtrair dois números, gastará mais tempo pesquisando como usar dc(e talvez o RPN em geral) do que economizará com métodos mais familiares.

Aaron Thomas
fonte
Sim, dei uma olhada de 3 minutos na Desk Calculator e sabia que não era para mim: eu era um TI, não um aluno da HP.
Fabby
2

Se você tem o gradle instalado, você tem ...

Se o groovy estiver no caminho correto, você poderá usar:

groovy -e "println 1+1"

Isso pode parecer um pouco redundante com todos os outros exemplos, mas:

  • groovy é uma linguagem poderosa
  • possivelmente o melhor suporte de biblioteca disponível
  • funções matemáticas poderosas e simples (como matemática de precisão arbitrária)
  • usa stdout redirecionável para sua saída, por isso é incrivelmente flexível (ótimo para usar dentro de arquivos em lotes com backticks `` e similares).

Se você não possui o java instalado, provavelmente não vale a pena instalar o groovy & java - é apenas uma opção se o groovy já estiver disponível.

Bill K
fonte
Não, na verdade não, mas uma boa idéia de qualquer maneira! :-) +1
Fabby
2

Já experimentou concalc ?

Descrição: a calculadora do console concalc é uma calculadora para o console do Linux. É apenas o algoritmo analisador do extcalc compactado em um simples programa de console. Você pode usá-lo se precisar de uma calculadora no seu shell. O concalc também é capaz de executar scripts escritos em uma linguagem de programação do tipo C.

$ concalc 1+1
2
$ concalc sqrt2
1.41421356237309505

Instale com:

sudo apt-get install concalc
Jan M.
fonte
11
prova ... graag gedaan ... :-D
Fabby
2

Antes de qualquer outra resposta brilhante ser publicada, acabei criando o script que /usr/local/bin/ccontinha:

#!/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

então: digitando c 1+1rendimentos 2! :-)

Nota 1: usei cporque esse comando não existe em nenhum sistema Unix que eu pudesse encontrar. Se você aliasse isso ao seu compilador c, use qualquer outra coisa curta e que não use.
Nota 2: Origem

Fabby
fonte
11
(1) Decidi usar echo "$*" | bc -lcomo o shebang que você usava /bin/she não sei se você tem o ksh / bash / zsh disponível. (2) Observe que você pode alterar a escala a ser calculada se executar a escala `c '= 60; 777/333', por exemplo. Espero que ajude @Fabby
Isaac
1

Se o python estiver instalado, você poderá executar muitas operações matemáticas por meio da linha de comando. Eu tentei fornecer um exemplo abaixo.

Eu usei python3você pode usar python. A diferença entre pythone python3ocorre quando a operação dividida (fracionária) ocorre, para evitar o problema, veja abaixo python vs python3 .

Nota: O mais recente all linux dist vem com o Python 2.7 e o Python 3.5 por padrão. Caso seja necessário instalar o python, clique aqui .

Adicionar, subtrair, multiplicar e dividir:

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

Módulo - remanescente da divisão:

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

Divisão de piso:

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

Expoente - x à potência de y (x ^ y):

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

Raiz quadrada (ex: √4 = 2):

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

Parte mais científica, você precisará da biblioteca matemática de importação . Ex:

O logaritmo natural de x = log (x):

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

O logaritmo da base 10 de x = log10 (x):

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

Fatorial (ex: 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

Para mais funções relacionadas à matemática, verifique aqui .

pythonVs python3:

-Para dividir: (use float):

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

-ao invés de

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

Além disso, você pode usar o terminal direto:

$ 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
>>> 

É isso aí. Feliz codificação!

AHJeebon
fonte
0

Ou bcou qalc.


Para ter automaticamente bcsempre um arredondamento para dois dígitos: (executá-lo -lé pesado para as coisas do dia a dia)

Edite seu ~/.bashrc:

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

Abra um novo shell e corra para bclá.

sjas
fonte
-1

Criando uma linha única:

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

Agora você pode usar matemática inteira simples:

$ c 1+1
2

$ c 25*4
100

$ c 25*4-10
90

$ c 20*5/4
25
WinEunuuchs2Unix
fonte
Isso já é discutido na resposta de Isaac .
Stephen Kitt
@StephenKitt Sim, votei na resposta muito detalhada de Isaac. Eu pensei que uma linha resumindo um pouco do que ele postou seria útil. O ${1}uso do parâmetro é exclusivo para todas as respostas.
WinEunuuchs2Unix
2
Convido você a examinar as razões pelas quais outras respostas não usam ${1};-)
Stephen Kitt