Tente isto:
ro='roundn(' # roundn open
rc=',n)' # roundn close
fun='exp\('
expression='exp(49/200)+(x-49/200)'
echo "$expression" |
perl -pe "s/$fun[^)]*\K\)/)$rc/g; s/(?<!\^)[0-9\/*]+[0-9]/$ro\$&$rc/g; s/$fun[^)]*/$ro\$&/g"
que deve dar a você:
roundn(exp(roundn(49/200,n)),n)+(x-roundn(49/200,n))
Sua expressão mais longa deve resultar em:
roundn(exp(roundn(49/200,n)),n)+roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))+roundn(1/2,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^2+roundn(1/6,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^3+roundn(1/24,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^4+roundn(1/120,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^5+roundn(1/720,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^6+roundn(1/5040,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^7+roundn(1/40320,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^8+roundn(1/362880,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^9+roundn(1/3628800,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n))^10+roundn(1/39916800,n)*roundn(exp(roundn(49/200,n)),n)*
(x-roundn(49/200,n) ^11
Explicação
-
/exp\([^)]*\K\)/)$rc/g
- fechar exp (), adicionar roundn close- para strings que começam com "exp (" e terminam com ")"
-
\K
faz a "exp (" uma correspondência de largura zero, então somente o paren de fechamento é substituído
-
s/(?<!\^)[0-9\/*]+[0-9]/$ro\$&$rc/g
- strings de dígitos com mult e div, surround com roundn open e roundn close- strings de dígitos que não começam com "^", mas podem conter "/" ou "*"
- deve ter dois ou mais caracteres no total - provavelmente há uma maneira melhor de fazer isso
- carat tem look-behind negativo (largura zero), por isso não é incluído quando a substituição é feita
-
s/exp\([^)]*/$ro\$&/g
- abrir exp (), adicionar roundn open- antes de "exp (" seguido de zero ou mais caracteres que não são ")", adicione roundn open
-
$ro
,$rc
e$fun
são variáveis do shell- colocar o script Perl entre aspas duplas permite que essas variáveis sejam expandidas
-
$&
contém toda a correspondência, exceto as porções de largura zero- escapar provavelmente não é necessário, mas eu fiz isso apenas no caso - para evitar confundir o shell
Não seria muito difícil fazer isso funcionar se houver mais de uma função. No entanto, ele provavelmente irá desmoronar completamente se eles estiverem aninhados.
Editar:
Aqui está uma versão do script Perl:
$ro = "roundn(";
$rc = ",n)";
$fun = "exp\(";
while (<>) {
s/$fun[^)]*\K\)/)$rc/g;
s/(?<!\^)[0-9\/*]+[0-9]/$ro$&$rc/g;
s/$fun[^)]*/$ro$&/g;
print
}
Execute assim:
perl script.pl < data.txt