Sed zum Löschen zwischen Trennzeichen, aber Beibehalten des ersten Trennzeichens

Sed zum Löschen zwischen Trennzeichen, aber Beibehalten des ersten Trennzeichens

Ich muss alles zwischen dem zweiten =und dem ersten /in einer Zeichenfolge löschen, aber das =an Ort und Stelle lassen. Ich habe viele, viele Dinge ausprobiert, das Neueste davon ist

sed -i 's/=[^/]*//

Antwort1

Nur auf Grundlage der Textbeschreibung und ohne Beispiele für Eingabe/Ausgabe bin ich zu Folgendem gekommen:

$ echo "foo=bar=baz/quux" | sed 's/\(.*=.*\)=.*\/\(.*\)/\1=\2/'
foo=bar=quux

Wie nahe kommt das Ihrem Wunsch?

Antwort2

Ich habe angefangen, über Look-Ahead- und Look-Behind-Assertionen zu schreiben, nur um festzustellen, dass sed sie nicht unterstützt! Das hier sollte funktionieren:

sed -i 's!\(=[^=]*=\)[^/]*/!\1!'

  • Da wir /im regulären Ausdruck Zeichen verwenden, ändern wir das Trennzeichen des sBefehls in!
  • \(=[^=]*=\)ist eine Erfassungsgruppe, die mit einem =Zeichen übereinstimmt, gefolgt von null oder mehr anderen Zeichen, gefolgt von einem weiteren =Zeichen. Dieser Teil ist erforderlich, um sicherzustellen, dass =vor der zu löschenden Teilzeichenfolge zwei Zeichen stehen, wie Sie sagten.
  • [^/]*/trifft auf alles zu, was zwischen den Trennzeichen und dem zweiten Trennzeichen steht
  • \1ersetzt die gesamte übereinstimmende Zeichenfolge durch alles, was mit der Erfassungsgruppe übereinstimmt\(=[^=]*=\)

Antwort3

Hier ist eine Lösung mitperl

$ echo 'foo=bar=baz/quux' | perl -pe 's|^([^=]+=){2}\K[^=/]+/||'
foo=bar=quux

$ echo 'abc=foo=bar=baz/quux' | perl -pe 's|^([^=]+=){2}\K[^=/]+/||'
abc=foo=bar=baz/quux

Wie aus den obigen Beispielen ersichtlich, beschränkt sich dies auf das Löschen von Text nur vom 2. =bis/

  • ^([^=]+=){2}\Kab Zeilenanfang Suche nach 2einer Folge von Nicht- =Text gefolgt von =. Das \Kbedeutet positive Rückschau, nicht Teil der Ersetzungszeichenfolge
  • [^=/]+/bedeutet ein oder mehrere Nicht- =/Zeichen, die mit enden/
    • Wird ein solcher Text gefunden, wird er gelöscht

Gleiche Lösung mitsed

$ echo 'foo=bar=baz/quux' | sed -E 's|^(([^=]+=){2})[^=/]+/|\1|'
foo=bar=quux

$ echo 'abc=foo=bar=baz/quux' | sed -E 's|^(([^=]+=){2})[^=/]+/|\1|'
abc=foo=bar=baz/quux

Es unterstützt keine Lookahead/Lookbehind-Konstrukte, daher wird die Capture-Gruppe verwendet und beim Ersetzen zurückverwiesen

verwandte Informationen