Wie ersetzt man eine Teilzeichenfolge aus einer Variablen?

Wie ersetzt man eine Teilzeichenfolge aus einer Variablen?

Ich versuche, Zeichen aus einer String-Variable zu entfernen. sedSo funktioniert es bei mir:

MYVAR=--23ho02123ware38384you443d34o3434ingtod38384day-%§*#sfrf
echo ${MYVAR} | sed -e 's/[a-z][a-z0-9\-]*//g'

und ich bekomme:

 --23%§*#

und das ist genau das, wonach ich suche. Die Zeichenfolge sollte mit einem Buchstaben beginnen und nur Buchstaben, Ziffern und einen Bindestrich (-) enthalten. Gibt es eine Möglichkeit, dies durch bashZeichenfolgenersetzung zu erreichen?

MYVAR=${MYVAR/[a-z][a-z0-9-]*/ }

Ich habe mehrere Kombinationen ausprobiert, aber keine davon funktionierte wie erwartet.

Antwort1

Sie müssten die erweiterten Glob-Operatoren von KSH verwenden (eine Teilmenge davon ist in bashwith shopt -s extglobund zshwith verfügbar set -o kshglob), um das Äquivalent von regulären Ausdrücken zu erhalten (allerdings mit einer anderen Syntax: *(x)für das Äquivalent von x*hier):

shopt -s extglob # for bash
# set -o kshglob # for zsh
printf '%s\n' "${MYVAR//[[:alpha:]]*([[:alnum:]-])/}"

Oder mit zsh extendedglobs, wobei das Äquivalent des regulären Ausdrucks *lautet #:

set -o extendedglob
printf '%s\n' ${MYVAR//[[:alpha:]][[:alnum:]-]#}

Einige Anmerkungen:

  • ${var/pattern/replacement}ersetzt nur das erste Vorkommen. Verwenden Sie , ${var//pattern/replacement}um jedes Vorkommen zu ersetzen (wie mit der gFlagge im Befehl sedvon s).
  • Sie haben als Ersatz ein Leerzeichen verwendet. Verwenden Sie ${var//pattern/}(oder ${var//pattern}), um es durch die leere Zeichenfolge zu ersetzen.
  • Sie möchten keine echobeliebigen Zeichenfolgen ausgeben
  • Außer in zsh,Variablenerweiterungen in Listenkontexten müssen in Anführungszeichen gesetzt werden
  • Das Verhalten wäre im Vergleich zu Ihrem sedAnsatz anders, wenn die Variable Zeilenumbruchzeichen enthält.
  • [a-z]stimmt mit Zeichen überein (Sortierelemente in einigen Tools), die zwischen aund liegen z, wobei die Liste je nach Gebietsschema, System und Tool variiert (beispielsweise stimmt [a-z]mit bash-4.3in einem en_GB.UTF-8Gebietsschema auf einem GNU-System mit A, X, é, , überein , aber nicht mit Z). Dies umfasst im Allgemeinen die 26 Kleinbuchstaben des englischen Alphabets, aber nicht unbedingt. [[:alpha:]]umfasst Zeichen (oder Sortierelemente), die alsalphabetisch(unabhängig von Groß- und Kleinschreibung) in Ihrem Gebietsschema. Wenn Sie nur die 26 englischen Buchstaben abgleichen möchten, verwenden Sie entweder [abcdefghijklmnopqrstuvwxyz]oder legen Sie das Gebietsschema auf C( LC_ALL=C) fest und verwenden Sie [a-z]oder [[:lower:]]nur für englische Kleinbuchstaben oder [a-zA-Z]/ [[:alpha:]]für beliebige englische Buchstaben.
  • [a-z0-9\-]in sedstimmt mit dem Backslash-Zeichen überein, verwenden Sie [a-z0-9-]stattdessen (das -muss an erster oder letzter Stelle stehen, um wörtlich genommen zu werden).

verwandte Informationen