Wie passt man das Leerzeichen in sed an?

218

Wie kann ich Leerzeichen in sed zuordnen? In meinen Daten möchte ich alle 3+ nachfolgenden Leerzeichen (Tabulator) abgleichen und durch 2 Leerzeichen ersetzen. Wie geht das?

Peter Smit
quelle

Antworten:

226

Die Zeichenklasse entspricht \sden Leerzeichen <tab>und <space>.

Zum Beispiel:

$ sed -e "s/\s\{3,\}/  /g" inputFile

ersetzt jede Folge von mindestens 3 Leerzeichen durch zwei Leerzeichen.


HINWEIS : Um die POSIX-Kompatibilität zu gewährleisten , verwenden Sie [[:space:]]stattdessen die Zeichenklasse \s, da letztere eine GNU sed-Erweiterung ist. Siehe die POSIX-Spezifikationen für sed und BREs

Mrucci
quelle
5
Aha! Es war der fehlende Schalter, der mich erwischt hat.
Sequoia McDowell
25
Ich musste auch den Schalter '-r' hinzufügen, der es erweiterten regulären Ausdrücken ermöglicht, sed zu veranlassen, '\ s' als Leerzeichen zu erkennen.
HUB
39
Mit Apples musste sedich [[:space:]]da \snichts anfangen. Vielleicht \sist eine GNU sed Erweiterung?
Jared Beck
2
@JaredBeck Dank, lief Ideen aus , warum meine einfache regex funktionierte nicht .. Das ist lahm, dachte ich \ s war Standard erweiterte Regex .. Auch -r nicht funktioniert und -E tat Hocke
Karthik T
3
Stattdessen [[:space:]könnte man verwenden, [[:blank:]]was nur horizontale Tabulatoren und Leerzeichen (aber keine Zeilenumbrüche, vertikalen Tabulatoren usw.) zusammenbringt.
Stefanct
67

Dies funktioniert unter MacOS 10.8:

sed -E "s/[[:space:]]+/ /g"
einige Ideen
quelle
2
Weißt du, ob dies auf allen Linux-Distributionen funktioniert?
Amphibient
2
Nicht generell wird GNU sed -E nicht haben. Aus der BSD sed-Manpage: "Die Optionen -E, -a und -i sind nicht standardmäßige FreeBSD-Erweiterungen und möglicherweise nicht auf anderen Betriebssystemen verfügbar."
Brad Koch
1
Warum benötigen Sie das Flag -E für den Operator +? Die meisten Ausdrücke würden wahrscheinlich gut mit * umgehen, dann würde dies auf anderen Plattformen funktionieren.
Samuel
5
@Samuel Wenn Sie * verwenden, entspricht der reguläre Ausdruck keinem oder mehreren Leerzeichen und Sie erhalten ein Leerzeichen zwischen jedem Zeichen und ein Leerzeichen an jedem Ende jeder Zeile. Wenn Sie das Flag -E nicht haben, möchten Sie sed "s/[[:space:]]\+/ /g"ein oder mehrere Leerzeichen abgleichen.
jbo5112
1
FWIW, NetBSDs sed unterstützt die -EFlagge ebenfalls.
Mcandre
13

Einige ältere Versionen von sed erkennen \ s möglicherweise nicht als Leerzeichen-Matching-Token. In diesem Fall können Sie eine Folge von Leerzeichen und Tabulatoren mit '[XZ] [XZ] *' abgleichen, wobei X ein Leerzeichen und Z ein Tabulator ist.

Marnix A. van Ammers
quelle
1
Für den speziellen Bedarf könnten Sie hier mit einem älteren sed Folgendes tun: $ sed 's / [XZ] [XZ] [XZ] [XZ] * / / g' Eingabedatei, wobei X ein Tabulator und Z ein Leerzeichen ist.
Marnix A. van Ammers
10
sed 's/[ \t]*/"space or tab"/'
Zac
quelle
2
Funktioniert dies garantiert auf jeder Version eines sedSystems? Wenn nicht, ist es möglicherweise erwähnenswert, wo dies in ähnlicher Weise funktioniert wie in den anderen Antworten, nur damit wir die Einschränkungen kennen und wo dies möglicherweise nicht das beabsichtigte Ergebnis hat.
Mokubai
2
Diese RE ist das, was ich verwende, um Leerzeichen abzugleichen. Es ist einfacher als Zeichenklassen, Tabulatoren oder Leerzeichen abzugleichen. Es werden nur die grundlegendsten Konventionen regulärer Ausdrücke verwendet, daher sollte es überall mit einer funktionalen Implementierung regulärer Ausdrücke funktionieren.
Nate
3
Unter Mac 10.9.5 gilt dies für Leerzeichen und 't'. Ich habe oben von Michael Douma verwendet, um Leerzeichen abzugleichen (es funktioniert auch mit -e).
Alien Life Form
Funktioniert auf meinem SUSE-System nicht vernünftig. Es stimmt mit der ersten Stelle in der Zeile überein, an der sich keine oder mehrere Leerzeichen vor dem ersten Zeichen befinden. Ich bezweifle, dass dies die beabsichtigte Funktion ist und sicherlich nicht der angeforderte Anwendungsfall. Ich glaube, Sie möchten das '*' für '\ +' (oder '\ {3, \}' für die Frage) ändern und möglicherweise ag am Ende des sed-Befehls setzen, um alle Vorkommen des Musters abzugleichen. Das Ersetzen von [\ t] durch [[: space:]] kann auch wünschenswert sein, falls die Zeile etwas anderes als Leerzeichen enthält.
jbo5112