Gibt es einen regulären Ausdruck für Folgendes, der Zeichen in einem Zeichensatz nur einmal entspricht? Mit anderen Worten, sobald ein Zeichen gefunden wurde, entfernen Sie es aus dem Satz.
Wenn grep dies nicht kann, gibt es ein eingebautes Dienstprogramm, das dies kann?
Beispiel:
Characters to match only once: spine
Eingang:
spine
spines
spin
pine
seep
spins
Ausgabe:
spine
spin
pine
BEARBEITEN:
Es gibt viele Möglichkeiten, um diese Ausgabe zu erzielen (ein Beispiel unten), aber ich suche nach einer Möglichkeit, dies zu tun, ohne den Befehl für jedes Muster anpassen zu müssen, mit dem ich übereinstimmen möchte.
grep '[spine]' input_file | grep -v 's.*s' | ... | grep -v 'e.*e'
grep
regular-expression
patterns
Steven
quelle
quelle
Antworten:
Mit regulären Ausdrücken im mathematischen Sinne ist dies möglich, aber die Größe der regulären Ausdrücke wächst exponentiell im Verhältnis zur Größe des Alphabets, sodass dies nicht praktikabel ist.
Es gibt einen einfachen Weg mit Negation und Rückreferenzen .
Die ersten
grep
wählt Linien , die mindestens eines von enthälteinps
; Die zweitegrep
lehnt Zeilen ab, die mehr als eine enthalten (z. B. Zulassenspinal tap
undspend
aber nichtfoobar
odersee
).quelle
Inspiriert von Ihrem Gesichtsausdruck kann ich mit egrep einen kürzeren finden:
das ist äquivalent zu
Und so erzeugt man den sed-Befehl automatisch aus der Eingabe:
Ich habe einen ähnlichen Ansatz mit grep versucht, konnte die Shell jedoch nicht davon überzeugen, das grep-Muster aus einer Variablen zu übernehmen. Wenn ich es jedoch wiedergab und das Ergebnis mit Ausschneiden und Einfügen einfügte, funktionierte der Befehl:
Vielleicht habe ich einen Fehler gemacht, vielleicht habe ich einen Fehler mit der variablen Erweiterung gemacht.
quelle