Lösung 1:
Verwenden Sie sed -e "s/[[:space:]]\+/ /g"
Hier ist eine Erklärung:
[ # start of character class
[:space:] # The POSIX character class for whitespace characters. It's
# functionally identical to [ \t\r\n\v\f] which matches a space,
# tab, carriage return, newline, vertical tab, or form feed. See
# https://en.wikipedia.org/wiki/Regular_expression#POSIX_character_classes
] # end of character class
\+ # one or more of the previous item (anything matched in the brackets).
Für Ihren Ersatz möchten Sie nur ein Leerzeichen einfügen. [:space:]
wird dort nicht funktionieren, da dies eine Abkürzung für eine Zeichenklasse ist und die Regex-Engine nicht wissen würde, welches Zeichen dort eingefügt werden soll.
Die +
muss in der Regex maskiert werden, weil mit der Regex-Engine von sed +
ist ein normales Zeichen, während \+
ist ein Metazeichen für „ein oder mehrere“. Auf Seite 86 von Reguläre Ausdrücke beherrschen , erwähnt Jeffrey Friedl in einer Fußnote, dass ed und grep Klammern mit Escapezeichen verwendeten, weil „Ken Thompson der Meinung war, dass reguläre Ausdrücke hauptsächlich für die Arbeit mit Ccode verwendet würden, wo die Notwendigkeit, rohe Klammern abzugleichen, häufiger wäre als Rückreferenzen.“ Ich nehme an, dass er genauso über das Pluszeichen dachte, daher die Notwendigkeit, es zu maskieren, um es als Metazeichen zu verwenden. Darüber kann man leicht stolpern.
In sed müssen Sie +
maskieren , ?
, |
, (
, und )
. oder verwenden Sie -r, um erweiterte Regex zu verwenden (dann sieht es aus wie sed -r -e "s/[[:space:]]\+/ /g"
oder sed -re "s/[[:space:]]\+/ /g"
Lösung 2:
Sie können den -s
verwenden ("squeeze")-Option von tr
:
$ tr -s '[:blank:]' <<< 'test.de. 1547 IN SOA ns1.test.de. dnsmaster.test.de. 2012090701 900 1000 6000 600'
test.de. 1547 IN SOA ns1.test.de. dnsmaster.test.de. 2012090701 900 1000 6000 600
Die [:blank:]
Zeichenklasse umfasst sowohl Leerzeichen als auch Tabulatoren.