Ich versuche, eine mathematische Operation mit auszuführen sed
, aber meine Variablen werden weiterhin als Zeichenfolgen behandelt. Die Eingabe ist von dieser Art:
$ echo 12 | sed 's/[0-9]*/&+3/'
$ 12+3
Ich möchte 15 als Ausgabe haben. Ich muss die Operation ausführen und das mathematische Ergebnis in nur einer Passage ersetzen, da ich das Programm als Python-Daemon stdout
ausführe und Passagen wie das Umleiten auf Dateien, Öffnen dieser Dateien, Ausführen von Operationen, Extrahieren des Ergebnisses und Ausführen vermeiden möchte der Ersatz. Für mich sed
scheint es das Beste zu sein, alles in einer Linie auszuführen.
Ich habe versucht, sowohl Input als auch Output auf verschiedene Arten zu übertragen
$ echo 12 | sed 's/[0-9]*/int(&+3)/'
$ echo 12 | sed 's/[0-9]*/\int(&+3)/'
$ echo 12 | sed 's/[0-9]*/\int(&+3)/'
das Ergebnis war jedoch immer ein Ausdruck des zweiten Feldes.
sed
Mathe zu tunAntworten:
Wenn Sie ehrlich gesagt sed verwenden möchten, ist dies der richtige Weg:
Eingang:
Ausgabe:
Ihre Mission ist es, Multiplikation zu implementieren, falls Sie dies akzeptieren möchten.
quelle
sed
ist hier nicht die beste Option, es führt keine native Arithmetik durch (siehe Inkrementieren einer Zahl, um zu erfahren, wie Sie dies möglicherweise tun könnten). Das könnte man machen mitawk
:Der beste zu verwendende Code hängt vom genauen Format Ihrer Eingabe ab und davon, was Sie tun möchten / müssen, wenn es sich nicht um einen numerischen Code handelt oder mehr als eine Zahl enthält.
Das kannst du auch nur mit
bash
:oder
expr
in ähnlicher Weise verwenden.quelle
Ich habe versucht, Ihre Herausforderung @Richter anzunehmen. Ich habe dazu einen Teil Ihres Codes verwendet:
Eingang:
Ausgabe: alle richtigen Ergebnisse
quelle
perl
erlaubt ein sehr ähnliches Konstrukt wiesed
's ... ein Unterschied ist, dassperl
es komplexere Dinge kann ...sed
ist sehr gut für einfache TextsubstitutionenAusgabe
quelle
perl -pe 's/[0-9]+/$&+3/e'
Füttere einfach die Schnur in einen Taschenrechner
quelle
Ich verstehe wirklich nicht, warum die extreme Komplexität der akzeptierten Antwort, eine der folgenden Maßnahmen, was Sie wollen:
oder
Ich denke, es könnte GNU sed erfordern, aber ich bin nicht sicher.
quelle
echo 12+3 | sed -r 's/([0-9]*) *\+ *([0-9]*)/expr \1 + \2/e'
Wenn Sie reguläre Ausdrücke und arithmetische Operationen unbedingt kombinieren müssen, wählen Sie eine Sprache, in der der Ersetzungsparameter des regulären Ausdrucks eine Rückruffunktion sein kann.
Perl, Ruby, JavaScript und Python sind solche Sprachen:
quelle
Eine andere einfache
bash
Lösung, die tatsächlich in einer Pipe funktioniert:quelle
Wenn Sie in etwas Bashismus mischen:
So extrahieren Sie die Nummer aus einem Text:
Ohne sed nur bash:
Ersetzt jede Nicht-Ziffer
${var//[^0-9]/}
und rechnet in doppelten runden Parens:$((x+3))
quelle
$((...))
wurde von POSIX eingeführt (der Bashismus ist$[...]
).${var//xxx/x}
ist ein kshism, das auch von zsh und bash kopiert wurde.sed -r
ist ein GNUismHier ist eine Perl-Lösung:
Wenn Sie die ersten Ziffern einer Zeichenfolge ändern möchten, können Sie Folgendes verwenden:
Wenn Sie es vorziehen, alle Zifferngruppen in einer Zeichenfolge zu ändern , können Sie den
/g
Modifikator wie folgt verwenden:quelle
Obwohl die Verwendung von sed expression großartig ist, hat es seine Grenzen. Zum Beispiel schlägt Folgendes fehl:
Um diese Einschränkung zu überwinden, greife ich einfach auf die eingebaute Potenz von pure sed zurück und implementiere folgenden Dezimaladdierer mit willkürlicher Länge:
Die Art und Weise, wie dies funktioniert, besteht darin, ein Dezimaladdierermodul zu implementieren, das zwei Eingangsziffern (A und B) sowie ein Übertragsbit hinzufügt und ein Summen- und ein Übertragsbit erzeugt. Die Idee stammt aus der Elektronik, wo Binäraddierer dasselbe für Binärzahlen tun. Alles, was wir tun müssen, ist, den Addierer über alle Ziffern zu schleifen, und wir können Zahlen beliebiger Länge hinzufügen (begrenzt durch den Speicher). Unten ist der Addierer in Aktion:
In genau der gleichen Weise kann man einen binären Addierer (oder einen beliebigen anderen Basisaddierer) implementieren. Sie müssen nur die Zeile ersetzen, die
s/$/;000=00001...
mit dem richtigen Substitutionsmuster für die angegebene Basis beginnt . Zum Beispiel:s/$/;000=00001=01010=01011=10100=01101=10110=10111=11/
ist ein Substitutionsmuster für einen binären Addierer beliebiger Länge.Sie können den Code, der auf meinem Github dokumentiert ist, anbringen .
quelle