Beispielsweise enthält eine Zeichenfolge: aaaaabbaabaabbaa. Ich möchte sie so kürzen, dass jedes „a“ bis zum „b“ vorne gelöscht wird, sodass das Ergebnis bbaabaabbaa sein muss.
Antwort1
Schauen Sie sich die Abschnitte anParametererweiterungUndMustervergleichIn man 1 bash
:
$ shopt -s extglob # enable extended glob operators
$ s=aaaaabbaabaabbaa
$ echo "${s##*(a)}"
bbaabaabbaa
$ s=bananasssssssss
$ echo "${s%%*(s)}"
banana
Antwort2
Mit GNU sed
:
sed -e 's/^\(.\)\1\{1,\}//'
das alle Zeichen abgleicht und löscht, die am Anfang einer Zeile mindestens einmal wiederholt werden. Es wird verwendet, ^\(.\)
um das erste Zeichen abzugleichen, und dann \1\{1,\}
um ein oder mehrere Zeichen mit Rückverweis auf diese Übereinstimmung abzugleichen.
Wenn Sie nur 1 oder mehr Wiederholungen des ersten Zeichens abgleichen möchten, können Sie einfach verwenden sed -e 's/^\(.\)\1\+//'
, aber das \{1,\}
Formular kann bei Bedarf problemlos für 2 oder mehr oder 3 oder mehr usw. geändert werden.
Antwort3
Nur zwei Zeilen:
$ a="aaaaabbaabaabbaaddd"
$ echo "${a#"${a%%[^"${a:0:1}"]*}"}"
bbaabaabbaaddd
Erläuterung der Aktion:
"${a:0:1}" ## Select the first char of $a: ='a'
[^ ]* ## All chars not 'a' from the end. ='bbaabaabbaaddd'
"${a%% }" ## Remove 'bbaabaabbaaddd' from the end of $a. ='aaaaa'
echo "${a# }" ## Remove 'aaaaa' from start of $a and echo it.
(-)Beide Erweiterungen benötigen Anführungszeichen, um * und / korrekt verarbeiten zu können. Es besteht immer noch das Problem, dass Backquotes normalerweise falsch verarbeitet werden:
a="\\\\*\\\\*****vdf*"; echo "${a#"${a%%[^"${a:0:1}"]*}"}"
Es wird gedruckt:
*\\*****vdf*
Die anfängliche wiederholte Zeichenfolge wurde korrekt entfernt, aber die nächsten vier Backslashs wurden in nur zwei umgewandelt.