it-swarm.com.de

Wie konvertiert man DOS/Windows-Newline (CRLF) in Unix-Newline (LF) in einem Bash-Skript?

Wie kann ich programmgesteuert (d. H. Nicht vi verwenden) DOS/Windows-Zeilenumbrüche in Unix konvertieren?

Die Befehle dos2unix und unix2dos sind auf bestimmten Systemen nicht verfügbar. Wie kann ich diese mit Befehlen wie sed/awk/tr emulieren?

276
Koran Molovik

Sie können tr verwenden, um von DOS nach Unix zu konvertieren. Dies ist jedoch nur dann sicher möglich, wenn CR in Ihrer Datei nur als erstes Byte eines CRLF-Bytepaars angezeigt wird. Dies ist normalerweise der Fall. Sie verwenden dann:

tr -d '\015' <DOS-file >UNIX-file

Beachten Sie, dass sich der Name DOS-file vom Namen UNIX-file unterscheidet. Wenn Sie versuchen, den gleichen Namen zweimal zu verwenden, werden keine Daten in der Datei gespeichert.

Sie können es nicht umgekehrt machen (mit Standard 'tr').

Wenn Sie wissen, wie ein Wagenrücklauf in ein Skript eingegeben wird (control-Vcontrol-M um control-M) einzugeben, dann:

sed 's/^M$//'     # DOS to Unix
sed 's/$/^M/'     # Unix to DOS

dabei ist das '^ M' das Kontroll-M-Zeichen. Sie können auch den Mechanismus bashANSI-C Quoting verwenden, um den Wagenrücklauf anzugeben:

sed $'s/\r$//'     # DOS to Unix
sed $'s/$/\r/'     # Unix to DOS

Wenn Sie dies jedoch sehr oft tun müssen (ungefähr mehr als einmal), ist es weitaus sinnvoller, die Konvertierungsprogramme zu installieren (z. B. dos2unix und unix2dos oder vielleicht dtou und utod ) und benutze sie.

299
tr -d "\r" < file

schau nach hier um Beispiele mit sed zu sehen:

# IN UNIX ENVIRONMENT: convert DOS newlines (CR/LF) to Unix format.
sed 's/.$//'               # assumes that all lines end with CR/LF
sed 's/^M$//'              # in bash/tcsh, press Ctrl-V then Ctrl-M
sed 's/\x0D$//'            # works on ssed, gsed 3.02.80 or higher

# IN UNIX ENVIRONMENT: convert Unix newlines (LF) to DOS format.
sed "s/$/`echo -e \\\r`/"            # command line under ksh
sed 's/$'"/`echo \\\r`/"             # command line under bash
sed "s/$/`echo \\\r`/"               # command line under zsh
sed 's/$/\r/'                        # gsed 3.02.80 or higher

Verwenden Sie sed -i für die direkte Konvertierung, z. sed -i 's/..../' file.

53
ghostdog74

Mit POSIX ist das kompliziert:

  • POSIX Sed unterstützt \r oder \15 nicht. Auch wenn dies der Fall ist, ist die -i-Option _____ nicht POSIX

  • POSIX Awk unterstützt \r und \15, jedoch ist die -i inplace-Option nicht POSIX

  • d2u und dos2unix sind keine POSIX-Dienstprogramme , aber ex ist

  • POSIX ex unterstützt nicht \r, \15, \n oder \12

Wagenrücklauf entfernen:

ex -bsc '%!awk "{sub(/\r/,\"\")}1"' -cx file

Wagenrücklauf hinzufügen:

ex -bsc '%!awk "{sub(/$/,\"\r\")}1"' -cx file
36
Steven Penny

Mit AWK können Sie:

awk '{ sub("\r$", ""); print }' dos.txt > unix.txt

Mit Perl können Sie:

Perl -pe 's/\r$//' < dos.txt > unix.txt
20
codaddict

Dieses Problem kann mit Standardwerkzeugen gelöst werden, aber es gibt genügend Fallen für Unvorsichtige, die ich empfehle, den Befehl flip zu installieren, der vor über 20 Jahren von Rahul Dhesi, dem Autor von Zoo..__, geschrieben wurde. Das Konvertieren von Dateiformaten ist ein hervorragender Job, während zum Beispiel die unbeabsichtigte Zerstörung von Binärdateien vermieden wird. Dies ist ein wenig zu einfach, wenn Sie einfach jede CRLF ändern, die Sie sehen ...

19
Norman Ramsey

Die bisher veröffentlichten Lösungen behandeln nur einen Teil des Problems und konvertieren die DOS/Windows-CRLF in Unix-LF. Ihnen fehlt, dass DOS CRLF als Zeile Trennzeichen verwendet, während Unix LF als Zeile Terminator verwendet. Der Unterschied ist, dass eine DOS-Datei (normalerweise) nach der letzten Zeile in der Datei nichts enthält, während Unix dies tut. Um die Konvertierung ordnungsgemäß durchzuführen, müssen Sie das letzte LF hinzufügen (es sei denn, die Datei hat die Länge Null, d. H. Enthält überhaupt keine Zeilen). Meine Lieblingsbeschwörung dafür (mit etwas mehr Logik, um CR-getrennte Dateien im Mac-Stil zu handhaben, und nicht belästigende Dateien, die bereits im Unix-Format vorliegen) ist etwas Perl:

Perl -pe 'if ( s/\r\n?/\n/g ) { $f=1 }; if ( $f || ! $m ) { s/([^\n])\z/$1\n/ }; $m=1' PCfile.txt

Beachten Sie, dass dadurch die Unixified-Version der Datei an stdout gesendet wird. Wenn Sie die Datei durch eine Unixified-Version ersetzen möchten, fügen Sie das -i-Flag von Perl hinzu.

14
Gordon Davisson

Wenn Sie keinen Zugriff auf dos2unix haben, diese Seite jedoch lesen können, können Sie dos2unix.py hier kopieren/einfügen.

#!/usr/bin/env python
"""\
convert dos linefeeds (crlf) to unix (lf)
usage: dos2unix.py <input> <output>
"""
import sys

if len(sys.argv[1:]) != 2:
  sys.exit(__doc__)

content = ''
outsize = 0
with open(sys.argv[1], 'rb') as infile:
  content = infile.read()
with open(sys.argv[2], 'wb') as output:
  for line in content.splitlines():
    outsize += len(line) + 1
    output.write(line + '\n')

print("Done. Saved %s bytes." % (len(content)-outsize))

Cross-posted von Superuser .

12

Super duper einfach mit PCRE;

Als Skript oder ersetzen Sie [email protected] durch Ihre Dateien.

#!/usr/bin/env bash
Perl -pi -e 's/\r\n/\n/g' -- [email protected]

Dadurch werden Ihre Dateien an Ort und Stelle überschrieben!

Ich empfehle, dies nur mit einem Backup (Versionskontrolle oder anders) durchzuführen.

8
ThorSummoner

Eine noch einfachere awk-Lösung ohne Programm:

awk -v ORS='\r\n' '1' unix.txt > dos.txt

Technisch '1' ist Ihr Programm, b/c awk erfordert eine Option, wenn die Option angegeben ist. 

UPDATE: Nachdem ich diese Seite zum ersten Mal seit langer Zeit wieder besucht hatte, wurde mir klar, dass noch niemand eine interne Lösung veröffentlicht hat.

while IFS= read -r line;
do printf '%s\n' "${line%$'\r'}";
done < dos.txt > unix.txt
6
nawK

Sie können vim programmgesteuert mit der Option -c {Befehl} verwenden:

Dos zu Unix:

vim file.txt -c "set ff=unix" -c ":wq"

Unix to dos:

vim file.txt -c "set ff=dos" -c ":wq"

"set ff = unix/dos" bedeutet, das Dateiformat (ff) der Datei in das Unix/DOS-Zeilenendeformat zu ändern

": wq" bedeutet, dass eine Datei auf die Festplatte geschrieben und der Editor beendet wird (wodurch der Befehl in einer Schleife verwendet werden kann).

5
Johan Zicola

So konvertieren Sie eine Datei an Ort und Stelle

dos2unix <filename>

Konvertierten Text in eine andere Datei ausgeben

dos2unix -n <input-file> <output-file>

Es ist bereits auf Ubuntu installiert und mit brew install dos2unix auf Homebrew verfügbar.


Ich kenne die Frage explizit nach Alternativen zu diesem Dienstprogramm, aber dies ist das erste Google-Suchergebnis für "Convert DOS in Unix-Zeilenenden".

4
Boris

interessanterweise in meinem Git-bash unter Windows sed "" hat der Trick schon funktioniert:

$ echo -e "abc\r" >tst.txt
$ file tst.txt
tst.txt: ASCII text, with CRLF line terminators
$ sed -i "" tst.txt
$ file tst.txt
tst.txt: ASCII text

Meine Vermutung ist, dass sed sie beim Lesen von Zeilen von der Eingabe ignoriert und immer Unix-Zeilenenden in die Ausgabe schreibt.

4
user829755

Das hat bei mir funktioniert 

tr "\r" "\n" < sampledata.csv > sampledata2.csv 
3
Santosh

TIMTOWTDI!

Perl -pe 's/\r\n/\n/; s/([^\n])\z/$1\n/ if eof' PCfile.txt

Basierend auf @GordonDavisson

Man muss die Möglichkeit von [noeol] in Betracht ziehen ...

2
lzc

Hatte nur die gleiche Frage zu erwägen (auf Windows-Seite, aber auch auf Linux anwendbar.) Überraschenderweise erwähnte niemand eine sehr automatisierte Möglichkeit, CRLF <-> LF-Konvertierungen für Textdateien mit der guten alten Zip -ll-Option (Info -Postleitzahl):

Zip -ll textfiles-lf.Zip files-with-crlf-eol.*
unzip textfiles-lf.Zip 

HINWEIS: Dadurch wird eine ZIP-Datei erstellt, die die ursprünglichen Dateinamen beibehält, aber die Zeilenenden in LF konvertiert. Dann würde unzip die Dateien als Zip-Datei extrahieren, d. H. Mit ihren ursprünglichen Namen (jedoch mit LF-Endungen), wodurch die lokalen Originaldateien ggf. überschrieben werden.

Relevanter Auszug aus dem Zip --help:

Zip --help
...
-l   convert LF to CR LF (-ll CR LF to LF)
2
vmsnomad

Sie können awk verwenden. Setzen Sie den Datensatztrenner (RS) auf einen regulären Ausdruck, der mit allen möglichen Zeilenumbrüchen übereinstimmt. Setzen Sie das Ausgabesatz-Trennzeichen (ORS) auf das Zeilenumbruch-Zeichen im Unix-Stil.

awk 'BEGIN{RS="\r|\n|\r\n|\n\r";ORS="\n"}{print}' windows_or_macos.txt > unix.txt
1
kazmer

Für Mac OSX, wenn Sie Homebrew installiert haben [ http://brew.sh/([1]

brew install dos2unix

for csv in *.csv; do dos2unix -c mac ${csv}; done;

Stellen Sie sicher, dass Sie Kopien der Dateien erstellt haben, da durch diesen Befehl die Dateien an Ort und Stelle geändert werden. __ Mit der Option -c mac wird der Switch mit osx kompatibel.

1
Ashley Raiteri

Unter Linux ist es einfach, ^ M (ctrl-M) in * nix newlines (^ J) mit sed umzuwandeln.

Auf der CLI wird es ungefähr so ​​aussehen, im Text kommt es tatsächlich zu einem Zeilenumbruch. Aber das geht über, dass es weiter geht:

sed 's/^M/\
/g' < ffmpeg.log > new.log

Sie erhalten dies, indem Sie ^ V (Strg-V), ^ M (Strg-M) und\(Backslash) während der Eingabe eingeben:

sed 's/^V^M/\^V^J/g' < ffmpeg.log > new.log
1
jet

Als Erweiterung der Unix-zu-DOS-Lösung von Jonathan Leffler, um sicher in DOS zu konvertieren, wenn Sie die aktuellen Zeilenenden der Datei nicht kennen:

sed '/^M$/! s/$/^M/'

Dadurch wird geprüft, ob die Zeile nicht bereits in CRLF endet, bevor sie in CRLF konvertiert wird.

0
Gannet

Ich habe ein Skript erstellt, das auf der akzeptierten Antwort basiert, sodass Sie es direkt konvertieren können, ohne am Ende eine zusätzliche Datei zu benötigen und anschließend zu entfernen und umzubenennen.

convert-crlf-to-lf() {
    file="$1"
    tr -d '\015' <"$file" >"$file"2
    rm -rf "$file"
    mv "$file"2 "$file"
}

wenn Sie eine Datei wie "file1.txt" haben, stellen Sie sicher, dass "file1.txt2" nicht bereits vorhanden ist oder überschrieben wird. Ich verwende dies als temporären Speicherort für die Datei.

0
OZZIE
sed --expression='s/\r\n/\n/g'

Da die Frage sed erwähnt, ist dies der einfachste Weg, sed zu verwenden. Der Ausdruck besagt, dass alle Wagenrückläufe und Zeilenvorschübe nur durch Zeilenvorschub ersetzt werden. Das ist es, was Sie brauchen, wenn Sie von Windows zu Unix wechseln. Ich habe bestätigt, dass es funktioniert.

0
John Paul