Estoy tratando de realizar una operación matemática con sed
, pero continúa tratando mis variables como cadenas. La entrada es de este tipo:
$ echo 12 | sed 's/[0-9]*/&+3/'
$ 12+3
Me gustaría tener 15 como salida. Necesito hacer la operación y reemplazar su resultado matemático en un solo pasaje, porque estoy ejecutando el programa como un demonio Python, y quiero evitar pasajes como redirigir stdout
archivos, abrir esos archivos, realizar operaciones, extraer el resultado, hacer el reemplazo. Para mí, sed
parece el mejor para realizar todo en una línea.
He intentado emitir entradas y salidas de varias maneras, 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)/'
pero el resultado siempre fue una impresión del segundo campo.
sed
para hacer matemáticasRespuestas:
Si honestamente quiere usar sed, este es el camino a seguir:
Entrada:
Salida:
Su misión, si elige aceptarla, es implementar la multiplicación.
fuente
sed
no es la mejor opción aquí, no hace aritmética de forma nativa (sin embargo, vea Incrementar un número para saber cómo podría hacerlo). Podrías hacer eso conawk
:El mejor código para usar dependerá del formato exacto de su entrada y de lo que quiera / necesite hacer si no es numérico, o contiene más de un número, etc.
También puede hacer esto solo con
bash
:o usar
expr
de una manera similar.fuente
Intenté aceptar tu desafío @Richter, esto es lo que hice usando parte de tu código:
Entrada:
Salida: todos los resultados correctos
fuente
perl
permite una construcción muy similar ased
la de ... una diferencia es queperl
puede hacer cosas más complejas ...sed
es muy bueno para las subtensiones de texto simplessalida
fuente
perl -pe 's/[0-9]+/$&+3/e'
solo introduce la cuerda en una calculadora
fuente
Realmente no entiendo por qué la extrema complejidad de la respuesta aceptada, cualquiera de los siguientes hace lo que quieres:
o
Creo que podría requerir GNU sed, pero no estoy seguro.
fuente
echo 12+3 | sed -r 's/([0-9]*) *\+ *([0-9]*)/expr \1 + \2/e'
Si definitivamente tiene que combinar expresiones regulares y operaciones aritméticas, elija un idioma donde el parámetro de reemplazo de la expresión regular pueda ser una función de devolución de llamada.
Perl, Ruby, JavaScript y Python son estos lenguajes:
fuente
Otra
bash
solución simple , que realmente funciona en una tubería:fuente
Si mezclas algo de bashism:
Para extraer el número de un texto:
Sin sed, solo bash:
reemplaza todos los no dígitos
${var//[^0-9]/}
y hace aritmética en pares dobles redondos:$((x+3))
fuente
$((...))
fue presentado por POSIX (el bashism es$[...]
).${var//xxx/x}
es un kshismo también copiado por zsh y bash.sed -r
es un GNUismAquí hay una solución de Perl:
Si prefiere cambiar el primer conjunto de dígitos encontrados en una cadena, puede usar:
Si prefiere cambiar todos los conjuntos de dígitos en una cadena, puede usar el
/g
modificador, de esta manera:fuente
Aunque el uso de la expresión sed es excelente, tiene sus limitaciones. Por ejemplo, el siguiente error:
Para superar esta limitación, simplemente debo recurrir al poder incorporado de sed puro e implementar el siguiente sumador decimal de longitud arbitraria:
La forma en que funciona es mediante la implementación de un módulo sumador decimal que agrega dos dígitos de entrada (A y B), así como Carry Bit y produce un Sum y Carry bit. La idea está tomada de la electrónica donde el sumador binario hace lo mismo para los números binarios. Todo lo que tenemos que hacer es recorrer el sumador sobre todos los dígitos y podemos agregar números arbitrarios de longitud (limitado por la memoria). A continuación se muestra el sumador en acción:
Exactamente de la misma manera se puede implementar un sumador binario (o cualquier otra base). Todo lo que tiene que hacer es reemplazar la línea que comienza
s/$/;000=00001...
con un patrón de sustitución adecuado para la base dada. Por ejemplo:s/$/;000=00001=01010=01011=10100=01101=10110=10111=11/
es un patrón de sustitución para sumador binario de longitud arbitraria.Puede ajustar el código documentado en mi github .
fuente