Was ist der einfachste Weg, um alle Wagenrückläufe \r
aus einer Datei in Unix zu entfernen ?
Was ist der einfachste Weg, um alle Wagenrückläufe \r
aus einer Datei in Unix zu entfernen ?
Antworten:
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 dos2unix
Ihnen aus irgendeinem Grund nichts zur Verfügung steht, sed
tun 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 sed
Ihnen aus irgendeinem Grund nichts zur Verfügung steht, ed
tun 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 :-)
\r
funktioniert nur mit GNU sed, sonst können Sie dies tun:sed `echo "s/\r//"`
sed
noch echo
erkennen \r
auf MacOs. In diesem Fall printf "\r"
scheint nur zu funktionieren.
sed "s/$(printf '\r')\$//"
$
sed $'s@\r@@g' |od -c
\n
tr -d '\r' < infile > outfile
Siehe tr (1)
tr
die \r
Escape-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).
outfile = infile
?
someProg <in >out && mv out in
.
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 \r
als Escape + r interpretiert und auf eine Ebene reduziert r
und alle Kleinbuchstaben entfernt r
. Deshalb die Antwort von Rob aus dem Jahr 2009 funktioniert nicht.
Durch Hinzufügen des /g
Modifikators wird sichergestellt, dass auch mehrere \r
entfernt werden und nicht nur der erste.
Es gibt ein Dienstprogramm namens dos2unix , das auf vielen Systemen vorhanden ist und auf den meisten problemlos installiert werden kann.
sed -i s/\r// <filename>
oder so; siehe man sed
oder 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\n
stattdessen ersetzen . Bare Line Feeds (Newline) unter Linux / Unix sind \n
.
s/\r//
scheint unter OS X keine Wagenrückläufe zu entfernen, sondern r
stattdessen 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-M
anstelle von \r
zu funktionieren.
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.
^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 -i
und dann "-es / \ r $ // g", um das Entfernen auf CRs bei EOL zu beschränken.
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.
Jemand anderes empfiehlt dos2unix
und 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 yum
wie folgt zu installieren :
yum install dos2unix
Dann können Sie es wie folgt verwenden:
dos2unix fileIWantToRemoveWindowsReturnsFrom.txt
Wenn Sie ein Betriebssystem (wie OS X) verwenden, das nicht über den dos2unix
Befehl verfügt, jedoch über einen Python-Interpreter (Version 2.5+), entspricht dieser Befehl dem folgenden dos2unix
Befehl:
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 ~/.bashrc
in der aktuellen Sitzung ausführen ), können Sie den dos2unix
Namen in der Befehlszeile auf dieselbe Weise wie in den anderen Beispielen verwenden.
Hier ist das Ding,
%0d
ist das Wagenrücklaufzeichen. Damit es mit Unix kompatibel ist. Wir müssen den folgenden Befehl verwenden.
dos2unix fileName.extension fileName.extension
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"
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.
Notepad++
den Befehl ' Edit / EOL Conversion / Unix (LF)
auf Ihrem Windows-System, bevor Sie die Datei auf Ihr Linux-System kopieren.
\r
auf 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 tcsh
bis sh
funktionieren und dennoch auch unter GNU / Linux funktionieren.
Getestet unter OS X, OpenBSD und NetBSD in tcsh
und unter Debian GNU / Linux in bash
.
sed
:In tcsh
auf einem O X, der folgende sed
könnte Schnipsel verwendet wird zusammen mit printf
, da weder sed
noch echo
Griff \r
in der speziellen Art und Weise , wie das GNU tut:
sed `printf 's/\r$//g'` input > output
tr
:Eine weitere Option ist tr
:
tr -d '\r' < input > output
sed
und tr
:Es scheint, dass tr
das Fehlen einer nachgestellten Newline in der Eingabedatei erhalten bleibt, während sed
unter 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 \r
oder ganz \n
am Ende der Datei.
Hier sind einige Beispieltests, mit denen sichergestellt werden kann, dass dies auf Ihrem System funktioniert, indem Sie printf
und verwenden hexdump -C
. Alternativ kann od -c
auch 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
%
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)
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
Sie können dies einfach tun:
$ echo $(cat input) > output
a * b
...