Wenn Sie ein Wort so qualifizieren , dass es eine Folge von 1 oder mehr nicht leeren Zeichen bedeutet , lautet die Antwort definitiv Ja, und dies ist auch sehr einfach. Dies liegt daran , [[:blank:]]*
und [^[:blank:]]*
sind boolean ergänzt und - alle Zeichen in einer Zeichenfolge versehen sind komplett - [[:blank:]]*
U [^[:blank:]]*
in der gleichen Weise , jede mögliche Zeichenfolge beschreiben kann der .*
Fall ist.
Wenn ein unvollständiges Zeichen oder eine anderweitig ungültige Bytesequenz in einer Zeichenfolge vorhanden ist, kann diese nicht von Kopf bis Ende erfolgreich beschrieben werden - wie dies manchmal bei der Interpretation einer Zeichenfolge in der falschen Codierung der Fall sein kann. Um ein vollständiges Zeichen pro Byte in einer beliebigen Zeichenfolge sicherzustellen, kann das Gebietsschema C wie folgt erzwungen werden:
LC_ALL=C sed ...
... wodurch Probleme vermieden werden, die die Zeichenfolge von Kopf bis Schwanz mit einem All-Inclusive-Muster wie .*
oder beschreiben([ ]*[^ ]*)*
Ein vollständig komplementäres Muster kann die Länge eines Strings so oft wie nötig von links nach rechts wiederholen, um beim letztmöglichen Auftreten zu landen, ohne das Muster zu unterbrechen. Dies ist definitiv eine reguläre Sprache.
BRE:
sed 's/\(\([^[:blank:]]*\)[[:blank:]]*\)*/\2/'
EHE:
sed -E 's/(([^[:blank:]]*)[[:blank:]]*)*/\2/'
In beiden Versionen werden weiterhin leere Zeilen gedruckt. Dies liegt daran, dass der Kleene- *
Stern mit null oder mehr Vorkommen eines Musters übereinstimmt. Es werden zuerst null oder mehr nicht leere Zeichen, dann null oder mehr leere Zeichen und dann null oder mehr Vorkommen der gruppierten Übereinstimmungen abgeglichen, bis die Zeichenfolge vollständig übereinstimmt.
Nachdem all dies übereinstimmt, geschieht die Magie beim Ersetzen - die Referenzen, die von Gruppen zurückgegeben werden \1
und \2
die letzten Vorkommen von jedem sind. Wenn also die Ersetzung erfolgt, wird die gesamte Zeichenfolge nur durch das letzte Vorkommen in einer Zeile mit null oder mehr nicht leeren Zeichen ersetzt - oder durch die Untergruppe \2
.
Dies funktioniert natürlich für jede mögliche Zeichenfolge - auch für eine leere -, was bedeutet, dass beide Formulare Zeilenumbrüche für Zeilen drucken, die nur leere Zeichen oder gar keine enthalten. Um dies zu handhaben, gibt es einige Dinge, die Sie tun können, aber lassen Sie uns zunächst die Eingabe der Zeichenklasse etwas vereinfachen:
b='[:blank:]'
Um nur zu drucken, wenn eine Zeile ein oder mehrere nicht leere Zeichen enthält, können Sie Folgendes tun:
BRE:
sed -n "s/\(\([^$b]*\)[$b]*\)*/\2/;/./p"
EHE:
sed -En "/[^$b]/s/(([^$b]*)[$b]*)*/\2/p"
- BRE-Fall - Die Ersetzung wird immer durchgeführt und nur Musterbereiche mit mindestens einem verbleibenden Zeichen werden gedruckt.
- ERE-Fall - Die Ersetzung wird immer nur in einem Musterbereich versucht, der mindestens ein nicht leeres Zeichen enthält.
Beide Formulare funktionieren mit beiden Methoden - solange die Syntax korrekt ist.
Der -n
Schalter deaktiviert das automatische Drucken des Musterbereichs, und das p
Flag für die s///
Ubstitution oder die /
Adressbefehle /
druckt die Ergebnisse nur, wenn dies erfolgreich ist.
Dieselbe Logik kann angewendet werden, um auch jedes {num}
Vorkommen zu erhalten , wie:
BRE:
sed -n "s/\([$b]*\([^$b]\{1,\}\)\)\{num\}.*/\2/p"
EHE:
sed -En "s/([$b]*([^$b]+)){num}.*/\2/p"
... wobei die num
in beiden regulären Ausdrücken durch eine Zahl ersetzt werden können, um nur das {num}
angegebene Vorkommen einer Folge von nicht leeren Zeichen zu drucken . Hier wird eine etwas andere Form verwendet, um sicherzustellen, dass die Anzahl nicht für das führende Leerzeichen in einer Zeichenfolge verzerrt ist.
Beachten Sie, dass der -E
ERE-Wechsel zu sed
sowohl in der BSD- als auch in der GNU-Version unterstützt wird, obwohl dies noch keine POSIX-Standardsyntax ist.
sed
?