sed: Führende Leerzeichen bei globaler Ersetzung ignorieren

sed: Führende Leerzeichen bei globaler Ersetzung ignorieren

Ich versuche, einen Sed-Befehl zu schreiben, um überzählige Leerzeichen in einer Datei zu ersetzen. Zwischen jedem Wort sollte nur ein Leerzeichen stehen, führende Leerzeichen und Tabulatoren sollten jedoch unverändert bleiben. Die Datei:

     This is     an indented      paragraph. The   indentation   should not be changed.
This is the     second   line  of the    paragraph. 

Wird werden:

     This is an indented paragraph. The indentation should not be changed.
This is the second line of the paragraph.

Ich habe Variationen ausprobiert von

/^[ \t]*/!s/[ \t]+/ /g

Ich bin für alle Ideen dankbar.

Antwort1

$ sed 's/\>[[:blank:]]\{1,\}/ /g' file
     This is an indented paragraph. The indentation should not be changed.
This is the second line of the paragraph.

Der von mir verwendete Ausdruck entspricht einem oder mehreren [[:blank:]](Leerzeichen oder Tabulatoren)nach einem Wortund ersetzt diese durch ein einzelnes Leerzeichen. Dies \>entspricht der Nullbreitegrenze zwischen einem Wortzeichen und einem Nicht-Wortzeichen.

Dies wurde mit dem nativen von OpenBSD getestet , aber ich denke, es sollte auch sedmit GNU funktionieren . GNU verwendet auch zum Abgleichen von Wortgrenzen.sedsed\b

Sie können sed -Edies auch verkürzen auf

sed -E 's/\>[[:blank:]]+/ /g' file

Auch hier gilt: Wenn \>es bei Ihnen mit GNU nicht funktioniert sed, verwenden Sie \bstattdessen.


Beachten Sie, dass das obige Ihren Beispieltext zwar richtig sortiert, aber nichtganzArbeit zum Entfernen von Leerzeichen nach der Interpunktion, wie nach dem ersten Satz in

     This is     an indented      paragraph.        The   indentation   should not be changed.
This is the     second   line  of the    paragraph.

Dafür reicht auch eine etwas kompliziertere Variante:

$ sed -E 's/([^[:blank:]])[[:blank:]]+/\1 /g' file
     This is an indented paragraph. The indentation should not be changed.
This is the second line of the paragraph.

Dadurch werden alle Nicht-Leerzeichen, auf die ein oder mehrere Leerzeichen folgen, durch das Nicht-Leerzeichen und ein einzelnes Leerzeichen ersetzt.

Oder mit Standard sed(und einer sehr kleinen Optimierung, indem die Ersetzung nur dann vorgenommen wird, wennzwei oder mehrLeerzeichen/Tabulatoren nach dem Nicht-Leerzeichen/Tabulator),

$ sed 's/\([^[:blank:]]\)[[:blank:]]\{2,\}/\1 /g' file
     This is an indented paragraph. The indentation should not be changed.
This is the second line of the paragraph.

Antwort2

POSIX:

sed 's/\([^[:space:]]\)[[:space:]]\{1,\}/\1 /g; s/[[:space:]]*$//'

Dadurch wird jede Folge von einem oder mehreren Leerzeichen, die auf ein Nicht-Leerzeichen folgen, durch dieses Nicht-Leerzeichen und ein einzelnes SPC-Zeichen ersetzt und die nachstehenden Leerzeichen entfernt, die leere Zeilen und Zeilen mit nachstehenden Leerzeichen abdecken würden (einschließlich der CRs am Ende von Zeilen aus Microsoft-Textdateien).

verwandte Informationen