Estou tentando executar uma operação matemática com sed
, mas continua a tratar minhas variáveis como seqüências de caracteres. A entrada é deste tipo:
$ echo 12 | sed 's/[0-9]*/&+3/'
$ 12+3
Eu gostaria de ter 15 como saída. Preciso fazer a operação e substituir seu resultado matemático em apenas uma passagem, porque estou executando o programa como um daemon Python e quero evitar passagens como redirecionar stdout
arquivos, abrir esses arquivos, executar operações, extrair o resultado, fazer a substituição. Para mim, sed
parece o melhor para executar tudo em uma linha.
Eu tentei converter a entrada e a saída de várias maneiras, como
$ echo 12 | sed 's/[0-9]*/int(&+3)/'
$ echo 12 | sed 's/[0-9]*/\int(&+3)/'
$ echo 12 | sed 's/[0-9]*/\int(&+3)/'
mas o resultado sempre foi a impressão do segundo campo.
sed
para fazer matemáticaRespostas:
Se você honestamente deseja usar o sed, este é o caminho a seguir:
Entrada:
Saída:
Sua missão, se você optar por aceitá-la, é implementar a multiplicação.
fonte
sed
não é a melhor opção aqui, não faz aritmética de forma nativa (consulte Incrementar um número para saber como você poderia fazê-lo). Você poderia fazer isso comawk
:A melhor parte do código a ser usada dependerá do formato exato da sua entrada e do que você deseja / precisa fazer se não for numérico ou se contiver mais de um número, etc.
Você também pode fazer isso apenas com
bash
:ou usando de
expr
maneira semelhante.fonte
Tentei aceitar o seu desafio @Richter, foi o que fiz usando parte do seu código:
Entrada:
Saída: todos os resultados corretos
fonte
perl
permite uma construção muito semelhante àsed
... uma diferença é queperl
pode fazer coisas mais complexas ...sed
é muito bom para subestações de texto simplessaída
fonte
perl -pe 's/[0-9]+/$&+3/e'
basta alimentar a corda em uma calculadora
fonte
Realmente não entendo por que a extrema complexidade da resposta aceita, uma das opções abaixo, faz o que você deseja:
ou
Eu acho que pode exigir o GNU sed, mas não tenho certeza.
fonte
echo 12+3 | sed -r 's/([0-9]*) *\+ *([0-9]*)/expr \1 + \2/e'
Se você definitivamente precisar combinar expressões regulares e operações aritméticas, escolha um idioma em que o parâmetro de substituição da expressão regular possa ser uma função de retorno de chamada.
Perl, Ruby, JavaScript e Python são essas linguagens:
fonte
Outra
bash
solução simples , que realmente funciona em um pipe:fonte
Se você misturar algum basismo:
Para extrair o número de um texto:
Sem sed, basta bash:
substitui todos os que não são dígitos
${var//[^0-9]/}
e faz aritmética em parênteses de dupla rodada:$((x+3))
fonte
$((...))
foi introduzido pelo POSIX (o basismo é$[...]
).${var//xxx/x}
é um kshism também copiado pelo zsh e bash.sed -r
é um GNUismAqui está uma solução Perl:
Se você preferir alterar o primeiro conjunto de dígitos encontrado em uma sequência, poderá usar:
Se você preferir alterar todos os conjuntos de dígitos em uma string, poderá usar o
/g
modificador, assim:fonte
Embora o uso da expressão sed seja ótimo, ele tem suas limitações. Por exemplo, o seguinte falha:
Para superar essa limitação, basta recorrer ao poder interno do puro sed e implementar o seguinte somador decimal de comprimento arbitrário:
A maneira como funciona é implementando o módulo somador decimal que adiciona dois dígitos de entrada (A e B), bem como Carry Bit e produz um bit Sum e Carry. A idéia é emprestada da eletrônica, onde o somador binário faz o mesmo para números binários. Tudo o que precisamos fazer é passar o somador por todos os dígitos e podemos adicionar números arbitrários de comprimento (limitados pela memória). Abaixo está o adicionador em ação:
Da mesma maneira, pode-se implementar o somador binário (ou qualquer outra base). Tudo o que você precisa fazer é substituir a linha que começa
s/$/;000=00001...
com o padrão de substituição apropriado para a base especificada. Por exemplo:s/$/;000=00001=01010=01011=10100=01101=10110=10111=11/
é o padrão de substituição do somador binário de comprimento arbitrário.Você pode ajustar o código documentado no meu github .
fonte