J'essaie d'effectuer une opération mathématique avec sed
, mais cela continue à traiter mes variables comme des chaînes. L'entrée est de ce genre:
$ echo 12 | sed 's/[0-9]*/&+3/'
$ 12+3
Je voudrais avoir 15 en sortie. Je dois effectuer l'opération et remplacer son résultat mathématique par un seul passage, car j'exécute le programme en tant que démon Python et je souhaite éviter les passages tels que la redirection stdout
sur des fichiers, l'ouverture de ces fichiers, l'exécution d'opérations, l'extraction du résultat, etc. le remplacement. Pour moi, sed
semble le meilleur pour effectuer tout en une seule ligne.
J'ai essayé de transtyper les entrées et les sorties de différentes manières, comme
$ echo 12 | sed 's/[0-9]*/int(&+3)/'
$ echo 12 | sed 's/[0-9]*/\int(&+3)/'
$ echo 12 | sed 's/[0-9]*/\int(&+3)/'
mais le résultat était toujours une impression du deuxième champ.
sed
les mathématiquesRéponses:
Si vous voulez honnêtement utiliser sed, voici le chemin à suivre:
Contribution:
Sortie:
Votre mission, si vous choisissez de l'accepter, est de mettre en œuvre la multiplication.
la source
sed
Ce n’est pas la meilleure option ici, il ne fait pas l’arithmétique de façon native (voir Incrémenter un nombre pour savoir comment vous pouvez éventuellement le faire). Vous pouvez le faire avecawk
:Le meilleur morceau de code à utiliser dépendra du format exact de votre entrée et de ce que vous voulez / devez faire s'il n'est pas numérique, s'il contient plus d'un nombre, etc.
Vous pouvez également le faire uniquement avec
bash
:ou en utilisant
expr
d'une manière similaire.la source
J'ai essayé d'accepter votre défi @Richter, voici ce que j'ai fait en utilisant une partie de votre code:
Contribution:
Sortie: tous les résultats corrects
la source
perl
permet une construction très similaire à cellesed
de ... une différence est que l'perl
on peut faire des choses plus complexes ...sed
c'est très bien pour les simples sous-textessortie
la source
perl -pe 's/[0-9]+/$&+3/e'
juste introduire la ficelle dans une calculatrice
la source
Je ne comprends vraiment pas pourquoi l'extrême complexité de la réponse acceptée, l'une ou l'autre des réponses ci-dessous fait ce que vous voulez:
ou
Je pense que cela pourrait nécessiter GNU sed, mais je ne suis pas sûr.
la source
echo 12+3 | sed -r 's/([0-9]*) *\+ *([0-9]*)/expr \1 + \2/e'
Si vous devez absolument combiner des expressions régulières et des opérations arithmétiques, choisissez un langage dans lequel le paramètre de remplacement de l'expression régulière peut être une fonction de rappel.
Perl, Ruby, JavaScript et Python sont de tels langages:
la source
Une autre
bash
solution simple , qui fonctionne réellement dans un tuyau:la source
Si vous mélangez un peu de bashisme:
Pour extraire le numéro d'un texte:
Sans sed, juste bash:
remplace chaque non-chiffre
${var//[^0-9]/}
et fait de l'arithmétique en doubles rondes:$((x+3))
la source
$((...))
a été introduit par POSIX (le bashisme est$[...]
).${var//xxx/x}
est un kshism également copié par zsh et bash.sed -r
est un GNUismVoici une solution Perl:
Si vous préférez modifier le premier ensemble de chiffres rencontrés dans une chaîne, vous pouvez utiliser:
Si vous préférez changer tous les ensembles de chiffres d'une chaîne, vous pouvez utiliser le
/g
modificateur, comme ceci:la source
Bien que l'utilisation de sed soit excellente, elle a ses limites. Par exemple, la suite échoue:
Pour surmonter cette limitation, il suffit de se tourner vers la puissance intrinsèque de sed sed et de mettre en œuvre l'additionneur décimal de longueur arbitraire suivant:
Cela fonctionne en mettant en œuvre un module d'additionneur décimal qui ajoute deux chiffres d'entrée (A et B) ainsi que Carry Bit et produit un bit Sum et Carry. L'idée est empruntée à l'électronique où l' additionneur binaire fait la même chose pour les nombres binaires. Tout ce que nous avons à faire est de boucler l'additionneur sur tous les chiffres et nous pouvons ajouter des nombres de longueur arbitraires (limités par la mémoire). Voici l'additionneur en action:
De la même manière, on peut implémenter un additionneur binaire (ou n’importe quelle autre base). Tout ce que vous avez à faire est de remplacer la ligne qui commence
s/$/;000=00001...
par un modèle de substitution approprié pour une base donnée. Par exemple:s/$/;000=00001=01010=01011=10100=01101=10110=10111=11/
est un modèle de substitution pour un additionneur binaire de longueur arbitraire.Vous pouvez adapter le code documenté sur mon github .
la source