Entfernen Sie den Wagenrücklauf unter Unix

Antworten:

261

Ich werde Sie meinen Wagen kehrt zu übernehmen ( CR, "\r", 0x0d) an den Enden der Linien anstatt nur blind innerhalb einer Datei (Sie sie in der Mitte der Saiten für alle kann ich weiß). Verwenden Sie diese Testdatei nur mit einem CRam Ende der ersten Zeile:

$ cat infile
hello
goodbye

$ cat infile | od -c
0000000   h   e   l   l   o  \r  \n   g   o   o   d   b   y   e  \n
0000017

dos2unix ist der richtige Weg, wenn es auf Ihrem System installiert ist:

$ cat infile | dos2unix -U | od -c
0000000   h   e   l   l   o  \n   g   o   o   d   b   y   e  \n
0000016

Wenn dos2unixIhnen aus irgendeinem Grund nichts zur Verfügung steht, sedtun Sie Folgendes:

$ cat infile | sed 's/\r$//' | od -c
0000000   h   e   l   l   o  \n   g   o   o   d   b   y   e  \n
0000016

Wenn sedIhnen aus irgendeinem Grund nichts zur Verfügung steht, edtun Sie dies auf komplizierte Weise:

$ echo ',s/\r\n/\n/
> w !cat
> Q' | ed infile 2>/dev/null | od -c
0000000   h   e   l   l   o  \n   g   o   o   d   b   y   e  \n
0000016

Wenn Sie keines dieser Tools auf Ihrer Box installiert haben, haben Sie größere Probleme als beim Versuch, Dateien zu konvertieren :-)

paxdiablo
quelle
13
\rfunktioniert nur mit GNU sed, sonst können Sie dies tun:sed `echo "s/\r//"`
Lapo
15
Weder sednoch echoerkennen \rauf MacOs. In diesem Fall printf "\r"scheint nur zu funktionieren.
Steve Powell
30
Um auf @ steves Kommentar sed "s/$(printf '\r')\$//"
einzugehen
7
Um das Problem auf dem Mac zu beheben, können Sie dem sed-String in einfachen Anführungszeichen auch $sed $'s@\r@@g' |od -c\n
Folgendes voranstellen
1
Ich bin mir nicht 100% sicher, aber für OS X könnte es funktionieren , wenn es CTRL-V + CTRL-Manstelle von verwendet wird \r.
240
tr -d '\r' < infile > outfile

Siehe tr (1)

Henrik Gustafsson
quelle
4
Nicht großartig: 1. funktioniert nicht an Ort und Stelle, 2. kann \ r auch nicht bei EOL ersetzen (was möglicherweise das ist, was Sie wollen oder nicht ...).
Tomasz Gandor
10
1. Die meisten Unixy-Tools funktionieren auf diese Weise, und es ist normalerweise der sicherste Weg, Dinge zu erledigen, da Sie immer noch das Original haben, wenn Sie es vermasseln. 2. Wie bereits erwähnt, besteht die Frage darin, Wagenrückläufe zu entfernen und keine Zeilenenden zu konvertieren. Aber es gibt viele andere Antworten, die Ihnen besser dienen könnten.
Henrik Gustafsson
1
Wenn Sie trdie \rEscape-Funktion nicht unterstützen , versuchen Sie es '\015'oder versuchen Sie es mit einem Literal '^M'(in vielen Shells an vielen Terminals erzeugt Strg-V Strg-M ein wörtliches Strg-M-Zeichen).
Tripleee
Wie ändert man es, wenn man will outfile = infile?
Christopher
3
@donlan, späte Antwort, aber Sie verwenden normalerweise etwas wie: someProg <in >out && mv out in .
Paxdiablo
38

Alte Schule:

tr -d '\r' < filewithcarriagereturns > filewithoutcarriagereturns
Sockel
quelle
32

Der einfachste Weg unter Linux ist meiner bescheidenen Meinung nach:

sed -i 's/\r$//g' <filename>

Die starken Anführungszeichen um den Substitutionsoperator 's/\r//'sind wesentlich . Ohne sie wird die Shell \rals Escape + r interpretiert und auf eine Ebene reduziert rund alle Kleinbuchstaben entfernt r. Deshalb die Antwort von Rob aus dem Jahr 2009 funktioniert nicht.

Durch Hinzufügen des /gModifikators wird sichergestellt, dass auch mehrere \rentfernt werden und nicht nur der erste.

wfjm
quelle
27

Es gibt ein Dienstprogramm namens dos2unix , das auf vielen Systemen vorhanden ist und auf den meisten problemlos installiert werden kann.

Emil H.
quelle
6
Manchmal wird es auch fromdos (und todos) genannt.
Anonym
Der Link ist jetzt nicht mehr
verfügbar.
7

sed -i s/\r// <filename>oder so; siehe man sedoder die Fülle von Informationen im Internet zur Verwendung von sed.

Eine Sache, auf die hingewiesen werden muss, ist die genaue Bedeutung von "Wagenrücklauf" oben; Wenn Sie wirklich das einzelne Steuerzeichen "Wagenrücklauf" meinen, ist das obige Muster korrekt. Wenn Sie allgemeiner CRLF (Wagenrücklauf und Zeilenvorschub, wie Zeilenvorschübe unter Windows implementiert sind) gemeint haben, möchten Sie wahrscheinlich \r\nstattdessen ersetzen . Bare Line Feeds (Newline) unter Linux / Unix sind \n.

rauben
quelle
Ich versuche -> sed 's / \ r \ n / = /' countryNew.txt> demo.txt zu verwenden, was nicht funktioniert. "Tiger" "Löwe."
Suvasis
Sollen wir das so verstehen, dass Sie auf einem Mac sind? Ich habe bemerkt, dass Darwin sed standardmäßig andere Befehle und Funktionen hat als die meisten Linux-Versionen ...
jsh
4
Zu Ihrer Information, das s/\r//scheint unter OS X keine Wagenrückläufe zu entfernen, sondern rstattdessen wörtliche Zeichen zu entfernen . Ich bin mir nicht sicher, warum das noch so ist. Vielleicht hat es etwas mit der Art und Weise zu tun, wie die Zeichenfolge zitiert wird? Als Workaround scheint die Verwendung CTRL-V + CTRL-Manstelle von \rzu funktionieren.
6

Wenn Sie ein Vi-Benutzer sind, können Sie die Datei öffnen und den Wagenrücklauf entfernen mit:

:%s/\r//g

oder mit

:1,$ s/^M//

Beachten Sie, dass Sie ^ M eingeben sollten, indem Sie Strg-V und dann Strg-M drücken.

Alex Giotis
quelle
2
Nicht großartig: Wenn die Datei in jeder Zeile CR enthält (dh eine korrekte DOS-Datei ist), lädt vim sie mit dem Dateityp = dos und zeigt überhaupt ^M-s nicht an. Um dies zu umgehen, gibt es eine Menge Tastenanschläge, für die vim nicht gemacht ist;). Ich würde einfach gehen sed -iund dann "-es / \ r $ // g", um das Entfernen auf CRs bei EOL zu beschränken.
Tomasz Gandor
6

Noch einmal eine Lösung ... Weil es immer noch eine gibt:

perl -i -pe 's/\r//' filename

Es ist schön, weil es vorhanden ist und in jeder Unix- / Linux-Variante funktioniert, mit der ich gearbeitet habe.

Allan Cano
quelle
3

Jemand anderes empfiehlt dos2unixund ich empfehle es auch sehr. Ich gebe nur mehr Details.

Wenn installiert, fahren Sie mit dem nächsten Schritt fort. Wenn nicht bereits installiert, würde ich empfehlen, es über yumwie folgt zu installieren :

yum install dos2unix

Dann können Sie es wie folgt verwenden:

dos2unix fileIWantToRemoveWindowsReturnsFrom.txt
James Oravec
quelle
2

Wenn Sie ein Betriebssystem (wie OS X) verwenden, das nicht über den dos2unixBefehl verfügt, jedoch über einen Python-Interpreter (Version 2.5+), entspricht dieser Befehl dem folgenden dos2unixBefehl:

python -c "import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))"

Dies behandelt sowohl benannte Dateien in der Befehlszeile als auch Pipes und Weiterleitungen wie dos2unix. Wenn Sie diese Zeile zu Ihrer ~ / .bashrc-Datei (oder einer entsprechenden Profildatei für andere Shells) hinzufügen:

alias dos2unix="python -c \"import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))\""

... Wenn Sie sich das nächste Mal anmelden (oder source ~/.bashrcin der aktuellen Sitzung ausführen ), können Sie den dos2unixNamen in der Befehlszeile auf dieselbe Weise wie in den anderen Beispielen verwenden.

Chris Johnson
quelle
2

Hier ist das Ding,

%0dist das Wagenrücklaufzeichen. Damit es mit Unix kompatibel ist. Wir müssen den folgenden Befehl verwenden.

dos2unix fileName.extension fileName.extension

Sireesh Yarlagadda
quelle
1

Versuchen Sie dies, um die dos-Datei in eine Unix-Datei zu konvertieren:

fromdos-Datei

Hawston
quelle
1

Für UNIX ... Ich habe festgestellt, dass dos2unix Unicode-Header aus meiner UTF-8-Datei entfernt hat. Unter Git Bash (Windows) scheint das folgende Skript gut zu funktionieren. Es verwendet sed. Beachten Sie, dass nur Zeilenumbrüche an den Zeilenenden entfernt und Unicode-Header beibehalten werden.

#!/bin/bash

inOutFile="$1"
backupFile="${inOutFile}~"
mv --verbose "$inOutFile" "$backupFile"
sed -e 's/\015$//g' <"$backupFile" >"$inOutFile"
LexieHankins
quelle
1

Wenn Sie eine X-Umgebung ausführen und einen geeigneten Editor (Visual Studio-Code) haben, würde ich der Empfehlung folgen:

Visual Studio-Code: Anzeigen von Zeilenenden

Gehen Sie einfach in die untere rechte Ecke Ihres Bildschirms. Der Visual Studio-Code zeigt Ihnen sowohl die Dateicodierung als auch die Konvention zum Zeilenende, gefolgt von der Datei. Mit einem einfachen Klick können Sie dies umschalten.

Verwenden Sie einfach visuellen Code als Ersatz für Notepad ++ in einer Linux-Umgebung, und schon kann es losgehen.

99Sono
quelle
Oder verwenden Sie Notepad++den Befehl ' Edit / EOL Conversion / Unix (LF)auf Ihrem Windows-System, bevor Sie die Datei auf Ihr Linux-System kopieren.
Jesse Chisholm
1

Entfernen \rauf jedem UNIX®-System:

Die meisten vorhandenen Lösungen in dieser Frage sind GNU-spezifisch und funktionieren unter OS X oder BSD nicht. Die folgenden Lösungen sollten auf vielen weiteren UNIX-Systemen und in jeder Shell von tcshbis shfunktionieren und dennoch auch unter GNU / Linux funktionieren.

Getestet unter OS X, OpenBSD und NetBSD in tcshund unter Debian GNU / Linux in bash.


Mit sed:

In tcshauf einem O X, der folgende sedkönnte Schnipsel verwendet wird zusammen mit printf, da weder sednoch echoGriff \rin der speziellen Art und Weise , wie das GNU tut:

sed `printf 's/\r$//g'` input > output

Mit tr:

Eine weitere Option ist tr:

tr -d '\r' < input > output

Unterschied zwischen sedund tr:

Es scheint, dass trdas Fehlen einer nachgestellten Newline in der Eingabedatei erhalten bleibt, während sedunter OS X und NetBSD (jedoch nicht unter OpenBSD oder GNU / Linux) eine nachgestellte Newline ganz am Ende der Datei eingefügt wird, selbst wenn die Eingabe fehlt nachlaufend \roder ganz \nam Ende der Datei.


Testen:

Hier sind einige Beispieltests, mit denen sichergestellt werden kann, dass dies auf Ihrem System funktioniert, indem Sie printfund verwenden hexdump -C. Alternativ kann od -cauch verwendet werden, wenn Ihr System fehlt hexdump:

% printf 'a\r\nb\r\nc' | hexdump -C
00000000  61 0d 0a 62 0d 0a 63                              |a..b..c|
00000007
% printf 'a\r\nb\r\nc' | ( sed `printf 's/\r$//g'` /dev/stdin > /dev/stdout ) | hexdump -C
00000000  61 0a 62 0a 63 0a                                 |a.b.c.|
00000006
% printf 'a\r\nb\r\nc' | ( tr -d '\r' < /dev/stdin > /dev/stdout ) | hexdump -C
00000000  61 0a 62 0a 63                                    |a.b.c|
00000005
% 
cnst
quelle
0

Ich habe Python dafür verwendet, hier mein Code;

end1='/home/.../file1.txt'
end2='/home/.../file2.txt'
with open(end1, "rb") as inf:
     with open(end2, "w") as fixed:
        for line in inf:
            line = line.replace("\n", "")
            line = line.replace("\r", "")
            fixed.write(line)
Raphael
quelle
0

Obwohl es ein älterer Beitrag ist, bin ich kürzlich auf dasselbe Problem gestoßen. Da ich alle Dateien in / tmp / blah_dir / umbenennen musste, da jede Datei in diesem Verzeichnis das nachfolgende Zeichen "/ r" (mit "?" Am Ende der Datei) hatte, konnte ich mir nur eine Skriptmethode vorstellen.

Ich wollte die endgültige Datei mit demselben Namen speichern (ohne ein Zeichen zu verfolgen). Bei sed war das Problem der Ausgabedateiname, den ich brauchte, um etwas anderes zu erwähnen (was ich nicht wollte).

Ich habe andere hier vorgeschlagene Optionen ausprobiert (aufgrund einiger Einschränkungen nicht als dos2unix angesehen), aber nicht funktioniert.

Ich habe es endlich mit "awk" versucht, was funktioniert hat, wo ich "\ r" als Trennzeichen verwendet habe und den ersten Teil genommen habe :

Trick ist:

echo ${filename}|awk -F"\r" '{print $1}'

Unter dem Skript-Snippet, das ich verwendet habe (wobei alle Dateien "\ r" als nachfolgendes Zeichen im Pfad / tmp / blah_dir / hatten), um mein Problem zu beheben:

cd /tmp/blah_dir/
for i in `ls`
  do
    mv   $i     $(echo $i | awk -F"\r" '{print $1}')
done

Hinweis: Dieses Beispiel ist nicht sehr genau, obwohl es meiner Arbeit nahe kommt (Erwähnung hier, um eine bessere Vorstellung davon zu geben, was ich getan habe)

Ashish K Srivastava
quelle
0

Ich habe dieses Shell-Skript erstellt, um das Zeichen \ r zu entfernen. Es funktioniert in Solaris und Red Hat:

#!/bin/ksh

LOCALPATH=/Any_PATH

for File in `ls ${LOCALPATH}`
do
   ARCACT=${LOCALPATH}/${File}
   od -bc ${ARCACT}|sed -n 'p;n'|sed 's/015/012/g'|awk '{$1=""; print $0}'|sed 's/ /\\/g'|awk '{printf $0;}'>${ARCACT}.TMP
   printf "`cat ${ARCACT}.TMP`"|sed '/^$/d'>${ARCACT}
   rm ${ARCACT}.TMP
done

exit 0
Heloderma Suspectum
quelle
-1

Sie können dies einfach tun:

$ echo $(cat input) > output
mma7
quelle
Ich weiß nicht, warum jemand '-1' gegeben hat. Dies ist eine vollkommen gute Antwort (und die einzige, die für mich funktioniert hat).
FractalSpace
1
Oh, sorry, ich war es. Warten Sie, schauen Sie, es funktioniert wirklich nicht für '\ r'!
Viacheslav Rodionov
1
@FractalSpace Das ist eine schreckliche Idee! Der gesamte Abstand in der Datei wird vollständig zerstört, und der gesamte Inhalt der Datei kann von der Shell interpretiert werden. Versuchen Sie es mit einer Datei, die eine Zeile enthält a * b...
Tom Fenech