Frage sed ersetzt alle Tabs und Leerzeichen durch ein einzelnes Leerzeichen


Ich habe eine Zeichenfolge wie die folgende:

test.de.          1547    IN      SOA     ns1.test.de. dnsmaster.test.de. 2012090701 900 1000 6000 600

jetzt möchte ich alle Tabs / Leerzeichen zwischen den Datensätzen durch nur ein einziges Leerzeichen ersetzen, damit ich es einfach mit verwenden kann cut -d " "

Ich habe Folgendes versucht:

sed "s/[\t[:space:]]+/[:space:]/g"

und verschiedene Varianten, aber es konnte nicht funktionieren. Irgendwelche Ideen?


19
2017-09-23 18:17


Ursprung


Versuch: sed -r -e "s / [\ t \] + / / g" - RJS
Tut dein cut unterstützt -w Möglichkeit? - Kondybas


Antworten:


Benutzen 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).

Zu Ihrer Ersetzung möchten Sie nur ein Leerzeichen einfügen. [:space:] wird dort nicht arbeiten, da das eine Abkürzung für eine Zeichenklasse ist und die Regex-Engine nicht wissen würde, welchen Charakter sie dort setzen soll.

Das + muss in der Regex mit der Regex-Engine von sed entkommen + ist ein normaler Charakter, während \+ ist ein Metazeichen für 'eins oder mehrere'. Auf Seite 86 von Reguläre Ausdrücke beherrschen, Jeffrey Friedl erwähnt in einer Fußnote, dass ed und grep entkomme Klammern, weil "Ken Thompson fühlte, dass reguläre Ausdrücke verwendet werden würden, um in erster Linie mit C zu arbeiten Code, bei dem man mit runden Klammern übereinstimmen müsste, wäre üblicher als eine Rückwärtsreferenzierung. "Ich nehme an, dass er beim Pluszeichen genauso empfand, daher musste er als Metazeichen entfernt werden. Es fällt leicht, dass er dabei stolperte .

In sed musst du fliehen +, ?, |, (, und ). oder verwende -r, um erweiterten Regex zu verwenden (dann sieht es so aus sed -r -e "s/[[:space:]]\+/ /g" oder sed -re "s/[[:space:]]\+/ /g"


31
2017-09-23 18:24



Werden dadurch auch Tabs entfernt? Kannst du erklären, warum du benutzt? \+ statt nur +? - Zulakis
Okay ich verstehe. [[: space:]] ist gleich [\ t \ r \ n \ v \ f]. Aber kannst du bitte erklären, warum du es benutzt? \+ - Zulakis
[[: space:]] entspricht "\ s", also ist die kürzere Version "s / \ s \ + / / g" - 3molo
Grundlegende reguläre Ausdrücke verwenden einen umgekehrten Schrägstrich vor einem Pluszeichen, wenn sie "eine oder mehrere der vorherigen Zeichen oder Gruppen", Quelle, bedeuten entwickler.apple.com/library/mac/#documentation/opensource/.... - 3molo
Ahh ich verstehe! Ich wusste nicht, dass es verschiedene Regex-Versionen gibt. Vielen Dank - Zulakis


Du kannst den ... benutzen -s ("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

Das [:blank:] Zeichenklasse umfasst sowohl Leerzeichen als auch Tabulatoren.


4
2018-02-01 04:09





Ich benutze gerne den folgenden Alias ​​für bash. Aufbauend auf dem, was andere geschrieben haben, verwenden Sie sed, um mehrere Leerzeichen mit einem einzelnen Leerzeichen zu suchen und zu ersetzen. Dies hilft, konsistente Ergebnisse beim Schneiden zu erhalten. Am Ende führe ich es noch einmal durch sed, um den Platz auf Tab zu ändern, damit es leichter zu lesen ist.

alias ll='ls -lh | sed "s/ \+/ /g" | cut -f5,9 -d" " | sed "s/ /\t/g"'

-2
2017-09-29 20:40



Wie beantwortet das die Frage? - Tonin