Amazon.de Widgets
Skip to content
19.März 2010 / Patrick

^M am Ende jeder Zeile

closeDieser Beitrag wurde vor über 3 Monaten veröffentlicht. Die darin beschriebenen Informationen sind mit Vorsicht zu geniessen, da sie bereits veraltet oder nicht mehr gültig sein könnten. Solltest du von Neuerungen oder Verbesserungen wissen, so freue ich mich über einen klärenden Kommentar.

Soeben habe ich ein paar Anpassungen in einem File einer Internetplattform vorgenommen.
Als ich die Daten dann mit VI auf der Konsole geöffnet hatte, stand an jedem Ende einer Zeile ein ^M.
Dies kommt daher, dass die Datei unter Windows geschrieben wurde und dadurch ein anderes Fileformat enthält. Dadurch bildet VI jeden Zeilenumbruch durch ein ^M ab.
Wer häufig zwischen den beiden Welten Linux und Windows unterwegs ist, der hat sicher schon oft festgestellt, dass eine unter Linux verfasste Textdatei unter Windows plötzlich keine Zeilenumbrüche mehr hat.

Zuerst habe ich versucht, dieses Überbleibsel der Windows-Welt direkt in VI selbst zu ersetzen:

1
%s/\^M//g

Dies funktionierte leider nicht, wäre ja auch zu schön gewesen.
VI sucht mit diesem Kommando nach den Zeichen ^ und M. Leider ist der Zeilenumbruch aber nur abgebildet als ^M, nicht aber auch als solches abgespeichert, wodurch VI nie etwas finden wird.

Die Lösung schlussendlich war zwar nicht ganz so komfortabel wie direkt per VI, hat aber ihren Zweck voll und ganz erfüllt:

1
perl -p -e 's/\r$//' < windowsdatei > linuxdatei

Natürlich funktioniert das ganze auch für alle Verräter der Linuxwelt (kein Flame, nur Spass) ;)

1
perl -p -e 's/\n/\r\n/' < linudatei > windowsdatei
  • stfischr

    Sieh an, da wird der VI immer so gelobt und dann kann er nicht mal so einfache Sachen, wie verschiedene Zeilenumbrüche handeln. Kann ja sogar mein 0815 Mousepad. :)

  • http://blog.256bit.org Christian

    So kann das auch nicht mit vim funktionieren. Was funktioniert, ist
    :s/\r/\r/
    oder, einfacher zu erzwingen, die Datei in einem bestimmten Fileformat zu schreiben, also
    zb:
    :w ++ff=unix

    Umgekehrt funktioniert auch, eine Datei mit einem bestimmten Fileformat zu lesen:
    :e ++ff=dos

    Christian

  • quintusfelix

    Genau für diesen Zweck gibt es die Tools dos2unix und unix2dos, bei Ubuntu im Paket tofrodos zu finden (http://en.wikipedia.org/wiki/Unix2dos)
    Grüße undso,
    der glückliche fünfte

  • http://campino2k.de Chris
  • http://blog.schaeufele.org/ daniel

    ein paar Korrekturen hätte ich da ;-)

    1. unter Vim lässt sich das Zeilenende mit “:set ff=dos” bzw. “:set ff=unix” ändern. Dann hat man solche Probleme nicht

    2. ^M kannst du unter Vim mit Strg+V Strg+M einfügen und so auch ersetzen

    3. um die Zeilenumbrüche in Dateien umzuwandeln, braucht man keine perl-Skripte. Dafür gibt es dos2unix und unix2dos

    P.S. @stfischr: Vim kann doch alles, man muss nur wissen wie *g*

  • http://kbct.de/ Knorkebrot

    Windows macht da auch nichts falsch. Genau genommen sind sie die einzigen, die es richtig machen. “\n” ist ja nur der Vorschub für die Zeile darunter, “\r” hingegen ist der Rücklauf, sodass man wieder an Stelle 0 der neuen Zeile steht.

    MßG,
    Knorke!

  • http://encodingit.ch Patrick

    @quintusfelix @daniel
    Da es ein Produktiver Server ist, wollte ich die Installation von weiteren Paketen vermeiden.

    @Christian @daniel
    Leider gibt es :set ff nicht. Liegt wohl daran, dass der Server nur VI und nicht VIM installiert hat.

    @Chris
    Die gegoogelte Lösung mit perl ging schneller als die Doku ;)

    @Knorkebrot
    Ich habe ja nie gesagt, dass Windows etwas falsch macht.

    @all
    Zu beachten, es ist VI nicht VIM…
    “Vim (Vi IMproved) ist eine Weiterentwicklung des Texteditors vi” (by Wikipedia)

  • fedov

    @Knorkebrot
    Ich kann das Verhalten von Windows ehrlich gesagt nicht so ganz nachvollziehen. Ein Rücklauf? Schreibst du noch viel mit der Schreibmaschine oder wieso kommt dir das so natürlich vor? Es ist einfach nur ein überflüssiges Zeichen! Schließlich kannst du auch Windows die beiden Zeichen (linefeed und carriage return) keineswegs getrennt voneinander sinnvoll einsetzen.
    (o.k. – angeblich stammt dieser Archaismus noch aus der Nadeldruckerzeit und hatte damals tatsächlich einen Sinn. Ist aber schon länger her und angesichts der Tatsache, das Unix viel älter ist als Windows, kann man nicht recht verstehen, dass ausgerechnet das jüngere System diesen obsoleten Ballast mitschleppt)

  • jeremias

    noch einfacher gehts mit dem tool
    dos2unix

    bsp.: dos2unix dos.txt
    oder andersrum
    unix2dos unix.txt

    und schon sind die “^M” weg.

    die kommen btw. vom CRLF, wohin gegen linux nur LF macht

  • http://encodingit.ch Patrick

    @jeremias
    Der Vorschlag kam weiter oben bereits schon 2 Mal… Und meine Antwort bleibt immer noch die selbe ;)

  • togi

    So gehts auch: %s/^M/\r/g

  • http://blog.rootserverexperiment.de/ Mattias (ohne ‘h’)

    Nicht jeder Server hat einen Perl-Interpreter installiert. Deshalb geht es auch mit sed – das ist sogar in der BusyBox dabei:

    # IN UNIX ENVIRONMENT: convert DOS newlines (CR/LF) to Unix format
    sed ‘s/.$//’

    # IN DOS ENVIRONMENT: convert Unix newlines (LF) to DOS format
    sed ‘s/$//’ # method 1
    sed -n p # method 2

    geklaut von: http://www.unixguide.net/unix/sedoneliner.shtml

  • http://www.last.fm/user/bas89 bas89

    „recode“ ist Bestandteil vieler Distributionen und kann solche Sachen von Haus aus, und vieles andere mehr :)

  • http://encodingit.ch Patrick

    @togi
    Wobei ^M mit Ctrl + V, M eingegeben werden muss, ansonsten ist es wieder das selbe wie bei meinem ersten Versuch.

    @Mattias (ohne ‘h’)
    Der einfachste und simpelste Weg… Das letzte Zeichen der Zeile löschen^^ Aber das Konvertieren von Unix nach DOS funktioniert bei mir nicht wirklich…

    @bas89
    Vielen Dank für den Tipp. War zwar auf meinem Server nicht drauf, aber sieht sehr nützlich aus das Tool.

  • http://demaya.de/wp demaya
  • http://my.opera.com/freedo/blog/ Fredo

    @fedov
    Man kann die Zeichen schon getrennt voneinander einsetzen. So kann man z.B. \r dafür benutzen, ohne Zeilenwechsel auf das erste Zeichen zurückzuspringen, um so z.B. eine Zeile zu überschreiben. So kann man z.B. in Konsolenanwendungen einen Fortschrittsbalken realisieren, indem die gleiche Zeile immer mit aktualisierten Werten überschrieben wird.

    Ob man ein Windows-\n (also ohne impliziten Carriage Return wie unter Unix) auch sinnvoll einsetzen könnte, weiß ich nicht. Vielleicht ist das daher bei Unix ganz praktisch gelöst.