Ich lade eine Datei in Variablen, das Problem ist, dass die Datei in Windows formatiert ist, glaube ich, so dass ich eine ^M
anstelle einer neuen Zeile bekomme.
Wie ändere ich es, wenn sich der Wert in der Variablen befindet? Ich bin mir bewusst, dass ich die Quelle in VI ändern kann (ich verwende übrigens OS X), aber ich kann die Originaldatei nicht ändern, sondern nur lesen, daher muss ich die ^M
aus der Variablen entfernen .
Nach meinem Verständnis \n
ist das nicht dasselbe wie ^M
, daher tr
funktioniert der Befehl nicht.
BEARBEITEN
Es scheint, dass die Frage nicht klar ist; Das ist also die Klarstellung.
Ich analysiere die Datei Zeile für Zeile; Jede Zeile hat 2 Werte, die durch Tabulatoren getrennt sind. Am Ende jeder Zeile befindet sich ein ^ M, es sieht folgendermaßen aus:
value1 value2^M
value3 value4^M
value5 value6^M
value7 value8^M
Mein Workflow ist ziemlich einfach und unkompliziert: Die txt-Datei enthält das, was Sie oben sehen, die Schleife separate Felder und für jede Zeile erhalten Sie die Werte; Wenn ich den zweiten Wert drucke, hat er das ^ M, das ich entfernen möchte
while IFS=$'\t' read -r -a line
do
Type1="${line[0]}"
Type2="${line[1]}"
done < $TXTFILE
Was bedeutet, dass es beim Drucken von Typ1 in Ordnung ist, aber die Variable Typ2 enthält das ^ M. Ich habe verwendet tr
und es hat nicht funktioniert, ich habe verwendet sed
, um das letzte Zeichen der Variablen zu entfernen, und es hat nicht funktioniert. Hoffe das klärt meine Frage. Vielen Dank
quelle
sed 's|\r||' file
anstelle vonfile
tr
aber die Frage ist viel zu weit gefasst. Wir wissen nicht, wie die Eingabe oder Ausgabe ist oder wie das Skript aussieht.Antworten:
^M
ist ein Wagenrücklauf (CR), der wie\r
fürtr
oder innerhalb angegeben werden kann$'…'
.\n
Gibt einen Zeilenvorschub (LF) an^J
. Ein Unix-Zeilenende ist LF, und ein Windows-Zeilentrennzeichen ist die zweistellige Folge CR-LF. Windows-Textdateien, die unter einem Unix-System wie Linux oder macOS angezeigt werden, sehen also so aus, als hätten sie^M
am Ende jeder Zeile außer am letzten Zeile, die ihre letzte neue Zeile fehlt.Sie können Wagenrückläufe aus einer Datei mit
tr
mit entfernenoder einfacher mit
dos2unix
.Um zu vermeiden, dass die Dateien geändert werden, können Sie jede Zeile beim Lesen überprüfen und CR am Ende einer Zeile entfernen. Wenn Sie beispielsweise durch
read
Tabulatoren getrennte Werte analysieren, entfernen Sie CR am Ende des letzten Felds. Die Parametererweiterung${VAR%$'\r'}
ergibt den WertVAR
minus einer nachfolgenden CR und den Wert von,VAR
wenn sie nicht mit CR endet.quelle
bash
, daher erwarte ich nicht, dass es Unterstützung bietet,line[-1]
für die Sie bash-4.3 oder höher benötigen. Es kommt mit,zsh
dass es unterstützt (und hat seit Jahrzehnten), aber beachten Sie, dass inzsh
, das erste Element ist$line[1]
, nicht$line[0]
(außer in ksh Emulation). Mit älterenbash
können Sie immer verwendenline[${#line[@]}-1]
Hier ist der einfachste Weg, um Ihr Skript zu reparieren. Fügen Sie einfach "Wagenrücklauf" als internes Feldtrennzeichen für den Lesebefehl hinzu:
quelle
zsh
wenn$IFS
es als Trennzeichen verwendet wird.zsh
;-)Verwendung (für kurze Saiten):
Beispiel:
Für längere Saiten benötigen Sie möglicherweise sed oder awk.
quelle
Eine allgemein nützlichere Methode zum Konvertieren des Inhalts von "DOS" -Dateien, die keine andere Inhaltsmarkierung als CR + LF-Zeilenenden haben (im Gegensatz zu nur Linux LF).
Für Ubuntu zuerst und nur einmal
die Verwendung wie unten angegeben, hier mit
od
zur Überprüfung der Ausgabe verwendetDies übersetzt nicht nur die Zeilenenden, sondern auch andere Sonderzeichen, abhängig von den Parametern
dos2unix
oder dem Gegenstückunix2dos
(das gleichzeitig installiert wird).quelle
dos2unix
ist nicht auf die Verwendung der FILE-Modifikation festgelegt, sondern "ein Filter" und kann in Pipes verwendet werden. genau wietr
. Es sollte auch vorgezogen werden,tr
da es Zeichensätze auf einer höheren Ebene verarbeitet, nicht nur Einzelbyte-Codes.