Ich versuche, Zeichen aus einer String-Variable zu entfernen. sed
So 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 bash
Zeichenfolgenersetzung 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 bash
with shopt -s extglob
und zsh
with 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
extendedglob
s, 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 derg
Flagge im Befehlsed
vons
).- 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
echo
beliebigen Zeichenfolgen ausgeben - Außer in
zsh
,Variablenerweiterungen in Listenkontexten müssen in Anführungszeichen gesetzt werden - Das Verhalten wäre im Vergleich zu Ihrem
sed
Ansatz anders, wenn die Variable Zeilenumbruchzeichen enthält. [a-z]
stimmt mit Zeichen überein (Sortierelemente in einigen Tools), die zwischena
und liegenz
, wobei die Liste je nach Gebietsschema, System und Tool variiert (beispielsweise stimmt[a-z]
mitbash-4.3
in einemen_GB.UTF-8
Gebietsschema auf einem GNU-System mitA
,X
,é
, , übereinẂ
, aber nicht mitZ
). 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 aufC
(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\-]
insed
stimmt 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).