Wie kann ich unter sed X ein Tabulatorzeichen mit sed einfügen?

68

Ich habe versucht:

echo -e "egg\t  \t\t salad" | sed -E 's/[[:blank:]]+/\t/g'

Was in ... endet:

eggtsalad

Und...

echo -e "egg\t  \t\t salad" | sed -E 's/[[:blank:]]+/\\t/g'

Was in ... endet:

egg\tsalad

Was ich möchte:

egg salad
Zach
quelle

Antworten:

89

Versuchen Sie: Ctrl+ Vund drücken Sie dann Tab.

Yan
quelle
Stellen Sie außerdem sicher, dass Sie Ihren sed-Ausdruck zitieren, wenn Sie wörtliche Leerzeichen einfügen, da sonst die Shell verwirrt wird. Das hat mich zuerst gestolpert.
Bobby Jack
2
Dies ist zum Kotzen, wenn Code in einem Forum oder was auch immer veröffentlicht wird. Wir können kein wörtliches TAB-Zeichen veröffentlichen.
Sam Watkins
2
@dongiulio Laut der Readline (3) -Manpage ist "CV" standardmäßig eine Anführungszeichen in Anführungszeichen, was bedeutet, dass "das nächste Zeichen, das Sie eingeben, wörtlich zur Zeile hinzugefügt wird".
Aissen
1
Warum, Apple ... WARUM?!
Schwenken
42

Verwenden Sie ANSI-C-Anführungszeichen: $'string'

sed $'s/foo/\t/'

Fügen Sie in Ihrem Beispiel einfach Folgendes hinzu $:

echo -e "egg\t  \t\t salad" | sed -E $'s/[[:blank:]]+/\t/g'
wisbucky
quelle
FWIW - Wenn Sie das $ using vim in einer 'sh'-Datei mit aktivierter Syntax hinzufügen, wird die Hervorhebung des' \ t'-Teils geändert, sodass selbst vim den Unterschied kennt!
DryLabRebel
1
Sehr nützlich, ich stimme zu, dass dies die Antwort sein sollte, aber kann jemand erklären, warum dieses magische $ so gut funktioniert?
Fırat Uyulur
25

OSX sed versteht nur \tdas Muster, nicht das Ersetzen überhaupt nicht \t, da es sich im Wesentlichen um das alte 4.2BSD handelt, seddas von 1982 oder später übrig geblieben ist. Verwenden Sie eine wörtliche Registerkarte (die in bashund vimist Ctrl+ V, Tab) oder GNU installieren coreutilseine angemessenere zu bekommen sed.

Geekosaurier
quelle
"Ja wirklich?" Ich konnte mich auch nicht dazu bringen, das Muster zu verstehen. Ich habe stattdessen [[: blank:]] verwendet. Vielleicht bin ich ihm nicht richtig entkommen. -- Vielen Dank.
Zach
In "Anführungszeichen hat die Shell den Backslash verarbeitet und sedwird ihn nicht sehen. Bei sedund regulären Ausdrücken im Allgemeinen wird das 'Zitieren stark bevorzugt.
Geekosaurier
Irgendeine Chance auf ein Codebeispiel? Es ist nicht wirklich wichtig, außer meine Neugier zu befriedigen. echo -e "Ei \ tsalad" | sed -Es / \ t / _ / 'scheint nicht zu funktionieren, ebenso wenig wie echo -e "Ei \ tsalad" | sed -Es / \\ t / _ / '
Zach
... seufz Lemme das herausarbeiten. Nur doppelt überprüft; Ich dachte, FreeBSD / OSX hätte eine bekommen sed, die etwas schlauer als die 4.2BSD war, aber tatsächlich ist die einzige Zeichenflucht, die es unterstützt, die \n.
Geekosaurier
Ich muss zugeben, dass ich regelmäßig von solchen Dingen gestolpert werde, weil der größte Teil meiner Erfahrung auf der Seite von System III / V liegt und BSD mir trotz mehrerer Jahre mit FreeBSD und OS X immer noch etwas fremd ist. (Und die meisten davon Meine sedVerwendung ist in Linux.)
Geekosaurier
15

Eine andere Option ist das $(printf '\t')Einfügen einer Registerkarte, z. B.:

echo -e "egg\t  \t\t salad" | sed -E "s/[[:blank:]]+/$(printf '\t')/g"
robinst
quelle
4
Dies hat den Vorteil, dass es portabler ist, als Ctrl+V Tabda Sie den gesamten Befehl kopieren, einfügen und einfacher freigeben können, ohne das Steuerzeichen zu verlieren.
Beporter
1

versuche awk

echo -e "egg\t  \t\t salad" | awk '{gsub(/[[:blank:]]+/,"\t");print}'
kurumi
quelle
-1

Eine Problemumgehung für die Registerkarte auf osx ist die Verwendung "\ "eines Escapezeichens gefolgt von vier Leerzeichen.

Wenn Sie versuchen, die letzte Instanz eines Musters zu finden, z. B. a, " })};"und nach diesem Muster eine Datei in eine neue Zeile einfügen, sieht Ihr sedBefehl in osx folgendermaßen aus:

sed -i '' -e $'/^\    \})};.*$/ r fileWithTextIWantToInsert' FileIWantToChange

Das Markup macht es unklar: Dem Escape-Zeichen müssen vier Leerzeichen folgen, um sed Zeichen , um ein Tabulatorzeichen auf osx zu registrieren.

Der gleiche Trick funktioniert, wenn dem Muster, das Sie suchen möchten, zwei Leerzeichen vorangestellt sind, und ich kann mir vorstellen, dass es auch funktioniert, um ein Muster zu finden, dem eine beliebige Anzahl von Leerzeichen vorangestellt ist.

Gao-Shan
quelle