129 Stimmen

Warum erkennt sed nicht die \t als Registerkarte?

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.

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 .

3voto

ghostdog74 Punkte 305138

Sie brauchen nicht zu verwenden sed um eine Ersetzung vorzunehmen, obwohl Sie eigentlich nur einen Tabulator vor der Zeile einfügen wollen. Die Ersetzung ist in diesem Fall ein kostspieliger Vorgang im Vergleich zum einfachen Ausdrucken, insbesondere wenn Sie mit großen Dateien arbeiten. Es ist auch einfacher zu lesen, da es sich nicht um Regex handelt.

z.B. mit awk

awk '{print "\t"$0}' $filename > temp && mv temp $filename

2voto

Raj Hassani Punkte 1467

Ich habe dies auf dem Mac verwendet:

sed -i '' $'$i\\\n\\\thello\n' filename

Dieser Link diente als Referenz

0voto

Roman Nurik Punkte 29557

sed unterstützt nicht \t noch andere Escape-Sequenzen wie \n und so weiter. Die einzige Möglichkeit, die ich gefunden habe, war, das Tabulatorzeichen tatsächlich in das Skript einzufügen, indem ich sed .

Daher sollten Sie vielleicht Perl oder Python verwenden. Hier ist ein kurzes Python-Skript, das ich geschrieben habe und das ich für alle Stream Regex'ing verwende:

#!/usr/bin/env python
import sys
import re

def main(args):
  if len(args) < 2:
    print >> sys.stderr, 'Usage: <search-pattern> <replace-expr>'
    raise SystemExit

  p = re.compile(args[0], re.MULTILINE | re.DOTALL)
  s = sys.stdin.read()
  print p.sub(args[1], s),

if __name__ == '__main__':
  main(sys.argv[1:])

2 Stimmen

Und die Perl-Version wäre der Shell-Einzeiler "perl -pe 's/a/b/' filename" oder "something | perl -pe 's/a/b/'"

0voto

Cees Timmerman Punkte 15076

Anstelle von BSD sed verwende ich Perl:

ct@MBA45:~$ python -c "print('\t\t\thi')" |perl -0777pe "s/\t/ /g"
   hi

0voto

justincbagley Punkte 11

Ich denke, andere haben dies für andere Ansätze hinreichend geklärt ( sed , AWK , usw.). Allerdings, mein bash -spezifische Antworten (getestet unter macOS High Sierra und CentOS 6/7) folgen.

1) Wenn OP eine Such- und Ersetzungsmethode ähnlich dem ursprünglichen Vorschlag verwenden wollte, würde ich vorschlagen, Folgendes zu verwenden perl dafür wie folgt. Anmerkungen: Backslashes vor Klammern für Regex sollten nicht notwendig sein, und diese Codezeile zeigt, wie $1 ist besser zu verwenden als \1 con perl Substitutionsoperator (z.B. pro Perl 5-Dokumentation ).

perl -pe 's/(.*)/\t$1/' $filename > $sedTmpFile && mv $sedTmpFile $filename

2) Allerdings, wie von ghostdog74 da die gewünschte Operation eigentlich darin besteht, einfach eine Registerkarte hinzufügen am Anfang jeder Zeile, bevor die tmp-Datei in die Eingabe-/Zieldatei ( $filename ), würde ich empfehlen perl erneut, jedoch mit folgender(n) Änderung(en):

perl -pe 's/^/\t/' $filename > $sedTmpFile && mv $sedTmpFile $filename
## OR
perl -pe $'s/^/\t/' $filename > $sedTmpFile && mv $sedTmpFile $filename

3) Natürlich ist die tmp-Datei überflüssig Es ist also besser, alles "an Ort und Stelle" zu machen (Hinzufügen von -i Flag) und vereinfachen die Dinge zu einem eleganteren Einzeiler mit

perl -i -pe $'s/^/\t/' $filename

CodeJaeger.com

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.

Powered by:

X