O
dc, para quem não conhece, é uma calculadora de notação polonesa.
Como qualquer aluno de programação sabe, pois certamente já teve que implementar algo em Linguagem de Programação ou Estrutura de Dados, a notação polonesa funciona sobre uma pilha.
Se para somar 200 com 500 se faz no bc (outra calculadora):
echo "200 + 300" | bc
No dc é um pouco diferente:
echo "200 300 + p" | dc
Onde se lê:
- Empilha o 200
- Empilha o 300
- Operador + precisa de dois parâmetros. Desempilha dois parâmetros e soma (200 e 300)
- Empilha o resultado da operação (500)
- Imprime (sem desempilhar) o valor do topo da pilha (comano 'p'). No caso 500
Um exemplo mais completo para ilustrar de vez o conceito:
echo "200 3 4 5 6 7 + * - + + p" | dc
- "200 3 4 5 6 7" são todos EMPILHADOS. A pilha está com o 7 sendo o TOPO
- Operador de +, desempilha o 7 e o 6 e soma: 7+6 = 13. Empilha o 13. A pilha está agora com "200 3 4 5 13"
- Operador de *, desempilha o 13 e o 5 e multiplica: 13*5 = 65. Empilha. A pilha agora está com "200 3 4 65"
- Operador de -, desempilha o 65 e o 4 e faz 4-65= -61. Empilha. A pilha está agora com "200 3 -61"
- Operador de +, desempilha o 3 e o -61 e soma: 3+ (-61) = -58. Empilha. A Pilha está agora com "200 -58"
- Operador de +, desempilha o 200 e o -58 e soma: 200 + (-58) = 142. Empilha. A pilha está agora com "142"
- Operador p, imprime o valor do topo. Imprime 142
O mais importante neste caso, o comando 'p', minúsculo, apenas imprime o que está no topo da pilha. Apenas um valor, não importa quantos estão na pilha.
Já o comando P (maiúsculo) faz uma impressão diferente. Ele imprime interpretando ASCII.
Veja:
echo "65 p" | dc # irá imprimir 65
echo "65 P" | dc # irá imprimir a letra A
O dc é um interpretador de comandos. Se você apenas digitar "dc" ele irá aguardar comandos. Por isto que se usa o echo junto com o pipe para evitar que ele aguarde que você digite algo.
Ou então pode-se usar o parâmetro -e, passando o que se quer digitar como parâmetro:
dc -e "65p"
$ dc -e "65P"
O último dc, se você está me acompanhando e reproduziu em seu terminal, imprimiu um A perdido, quase não notado antes do prompt.
Seria interessante ter uma quebra de linha, certo?
No mundo Unix a quebra de linha é reproduzida apenas com o caractere LF (Line Feed) que na tabela ASCII corresponde ao valor 10.
No mundo DOS uma quebra de linha precisa de LF+CR (Line Feed + Enter) que na tabela ASCCI é 10 e 13. Para quem não entendeu, isto explica porque o teu código em bash feito no
Linux não abre corretamente no (sic) notepad. Isto é tão comum que já existem nas distribuições aplicativos como dos2unix e unix2dos apenas para converter de e para o formato de texto DOS.
Então para termos a nossa quebra de linha:
dc -e "65 P 10 P"
Meu nome neste formato:
dc -e "69P 108P 103P 105P 111P 32P 83P 99P 104P 108P 101P 109P 101P 114P 10P"
Deixei espaço em branco para facilitar, mas ele não é necessário:
dc -e "69P108P103P105P111P32P83P99P104P108P101P109P101P114P10P"
Isto já é um pouco nerd, mas ainda não tem graça. Tem muito 'P' aí e quem conhece ASCII logo iria sacar: "69 => 'E'