sed "s/\(.*\)/\t\1/" $filename > $sedTmpFile && mv $sedTmpFile $filename
Ich erwarte dies sed
Skript zum Einfügen einer tab
vor jeder Zeile in $filename
ist es jedoch nicht. Aus irgendeinem Grund fügt es eine t
stattdessen.
sed "s/\(.*\)/\t\1/" $filename > $sedTmpFile && mv $sedTmpFile $filename
Ich erwarte dies sed
Skript zum Einfügen einer tab
vor jeder Zeile in $filename
ist es jedoch nicht. Aus irgendeinem Grund fügt es eine t
stattdessen.
Ah ja; zur Klarstellung: nicht alle Versionen von sed verstehen \t
im Ersetzungsteil des Ausdrucks (er erkennt \t
im Teil für den Mustervergleich)
Awwwwwwwwwwwwwwwwwwwwwwwww, das ist ziemlich interessant. Und seltsam. Warum wird es an einer Stelle erkannt, an der anderen aber nicht...?
Von einem Skript aus aufgerufen, wird das nicht funktionieren: Tabs würden von sh ignoriert werden. Der folgende Code aus einem Shell-Skript fügt zum Beispiel $TEXT_TO_ADD hinzu, ohne ihm eine Tabulierung voranzustellen: sed "${LINE}a \\ $TEXT_TO_ADD " $FILE .
Sie waren auf der richtigen Spur mit dem $'string'
aber es fehlen Erklärungen. In der Tat vermute ich, dass Sie aufgrund der extrem umständlichen Verwendung wahrscheinlich ein unvollständiges Verständnis haben (wie die meisten von uns mit bash). Siehe meine Erklärung unten: stackoverflow.com/a/43190120/117471
Denken Sie daran, dass BASH keine Variablen wie $TAB
in einfachen Anführungszeichen, Sie müssen es also in doppelten Anführungszeichen verwenden.
@sedit war auf dem richtigen Weg, aber es ist ein bisschen umständlich, eine Variable zu definieren.
Der Weg, dies in der Bash zu tun, besteht darin, ein Dollarzeichen vor die in Anführungszeichen gesetzte Zeichenkette zu setzen.
$ echo -e '1\n2\n3'
1
2
3
$ echo -e '1\n2\n3' | sed 's/.*/\t&/g'
t1
t2
t3
$ echo -e '1\n2\n3' | sed $'s/.*/\t&/g'
1
2
3
Wenn Ihre Zeichenkette eine Variablenerweiterung enthalten muss, können Sie Zeichenketten in Anführungszeichen wie folgt zusammenstellen:
$ timestamp=$(date +%s)
$ echo -e '1\n2\n3' | sed "s/.*/$timestamp"$'\t&/g'
1491237958 1
1491237958 2
1491237958 3
In bash $'string'
verursacht "ANSI-C-Erweiterung". Und das ist es, was die meisten von uns erwarten, wenn wir Dinge verwenden wie \t
, \r
, \n
, usw. Von: https://www.gnu.org/software/bash/manual/html_node/ANSI_002dC-Quoting.html#ANSI_002dC-Quoting
Wörter der Form $'string' werden besonders behandelt. Das Wort erweitert sich zu String , wobei Zeichen mit Schrägstrich gemäß den Angaben in dem ANSI C-Standard. Backslash-Escape-Sequenzen, falls vorhanden, werden dekodiert...
Das erweiterte Ergebnis steht in einfachen Anführungszeichen, als ob das Dollarzeichen nicht vorhanden wäre nicht vorhanden gewesen wäre.
Ich persönlich halte die meisten Bemühungen, Bash zu vermeiden, für albern, weil die Vermeidung von Bashismen Ihren Code NICHT* portabel macht. (Ihr Code wird weniger spröde sein, wenn Sie ihn in Shebang bash -eu
als wenn Sie versuchen, die Bash zu vermeiden und die sh
[es sei denn, Sie sind ein absoluter POSIX-Ninja].) Aber anstatt eine religiöse Diskussion darüber zu führen, werde ich Ihnen einfach die BESTE* Antwort geben.
$ echo -e '1\n2\n3' | sed "s/.*/$(printf '\t')&/g"
1
2
3
* BESTE Antwort? Ja, denn ein Beispiel dafür, was die meisten Anti-Bash-Shell-Scripter in ihrem Code falsch machen würden, ist die Verwendung von echo '\t'
wie in @robrecord's Antwort . Das funktioniert für GNU echo, aber nicht für BSD echo. Das wird von The Open Group erklärt unter http://pubs.opengroup.org/onlinepubs/9699919799/utilities/echo.html#tag_20_37_16 Und dies ist ein Beispiel dafür, warum der Versuch, Bashismen zu vermeiden, in der Regel scheitert.
Es ist lustig, dass Sie eine "GNU echo"-spezifische Funktion verwenden (Interpretation von \t als Tabulatorzeichen), um einen "BSD sed"-spezifischen Fehler zu beheben (Interpretation von \t als 2 getrennte Zeichen). Vermutlich, wenn Sie "GNU echo" haben, haben Sie auch "GNU sed". In diesem Fall bräuchten Sie echo nicht zu benutzen. Mit BSD echo echo '\t'
wird 2 separate Zeichen ausgeben. Der POSIX-portable Weg ist die Verwendung von printf '\t'
. Deshalb sage ich: Versuchen Sie nicht, Ihren Code portabel zu machen, indem Sie keine Bash verwenden. Es ist schwieriger als Sie denken. verwenden bash
ist das Tragbarste, was die meisten von uns tun können.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
2 Stimmen
Da sed von Plattform zu Plattform unterschiedlich sein kann (insbesondere BSD/MacOSX gegenüber Linux), kann es hilfreich sein, die Plattform anzugeben, auf der Sie sed verwenden.
0 Stimmen
Sed "s/(.*)/# \1 /" $Dateiname | tr '#' ' \t ' > $sedTmpFile && mv $sedTmpFile $filename.
0 Stimmen
Für OS X (macOS) Benutzer, siehe diese Frage .
0 Stimmen
Siehe unix.stackexchange.com/a/145385/199866