Wie finde ich Zeilenenden in einer Textdatei heraus?

304

Ich versuche, etwas in Bash zu verwenden, um mir die Zeilenenden in einer Datei anzuzeigen, die gedruckt und nicht interpretiert wird. Die Datei ist ein Speicherauszug von SSIS / SQL Server, der von einem Linux-Computer zur Verarbeitung eingelesen wird.

  • Gibt es irgendwelche Schalter innerhalb vi, less, more, etc?

  • Zusätzlich zu den Zeilenenden muss ich wissen, um welche Art von Zeilenende es sich handelt ( CRLFoder LF). Wie finde ich das heraus?

Marco Ceppi
quelle
1
Allgemeiner Tipp: Wenn Sie eine Vorstellung davon haben, welchen * nix / cygwin-Befehl Sie verwenden könnten, können Sie jederzeit die Manpage anzeigen, um nach Schaltern zu suchen, die Ihnen möglicherweise die Funktionalität bieten, die Sie benötigen. ZB , man less.
David Rivers

Antworten:

421

Mit dem fileDienstprogramm können Sie die Art der Zeilenenden angeben.

Unix:

$ file testfile1.txt
testfile.txt: ASCII text

"DOS":

$ file testfile2.txt
testfile2.txt: ASCII text, with CRLF line terminators

So konvertieren Sie von "DOS" nach Unix:

$ dos2unix testfile2.txt

So konvertieren Sie von Unix nach "DOS":

$ unix2dos testfile1.txt

Das Konvertieren einer bereits konvertierten Datei hat keine Auswirkung, so dass es sicher ist, blind ausgeführt zu werden (dh ohne vorher das Format zu testen), obwohl wie immer die üblichen Haftungsausschlüsse gelten.

Bis auf weiteres angehalten.
quelle
9
Diese werden jetzt manchmal als "fromdos" bzw. "todos" bezeichnet (wie es in Ubuntu 10.4+ der Fall ist)
Jess Chadwick
3
@JessChadwick: Ja, aber nur, wenn Sie das tofrodosPaket explizit mit installieren sudo apt-get install tofrodos- genau so, wie Sie es ausführen müssten sudo apt-get install dos2unix, um dos2unixund zu erhalten unix2dos.
mklement0
Eigentlich kann dos2unix nicht die ganze Arbeit machen, ich denke stackoverflow.com/questions/23828554/dos2unix-doesnt-convert-m gibt die beste Antwort
Nathan
@ Nathan: Woran dos2unixscheitert? Das OP bei dieser Frage beschreibt das Problem nur vage.
Bis auf weiteres angehalten.
Der Befehl @DennisWilliamson file vor und nach dem Befehl dos2unix hat dieselbe Ausgabe erhalten: xxx.c C-Quelle, ASCII-Text, mit CR-, LF-Zeilenabschlüssen. Ich fand diese c-Datei hat ^ M in der Mitte der Zeile, die xxxxxxx ^ M xxxxxxx
Nathan
127

In vi...

:set list Zeilenenden zu sehen.

:set nolist wieder normal werden.

Während ich glaube nicht , können Sie sehen , \noder \r\nin vi, können Sie es (UNIX, DOS, etc.) zu schließen , welche Zeilenende hat Art von Datei sehen , welche ...

:set ff

Alternativ können bashSie die Retouren verwenden od -t c <filename>oder nur od -c <filename>anzeigen.

Ryan Berger
quelle
26
Leider glaube ich nicht, dass vi diese spezifischen Charaktere zeigen kann. Sie können od -c <Dateiname> ausprobieren, von dem ich glaube, dass es \ n oder \ r \ n anzeigt.
Ryan Berger
3
In der Kategorie "Für das, was es wert ist" können Sie nach CRLF im Dos-Stil suchen, indem Sie grep --regex = "^ M" eingeben, wobei ^ M STRG + V STRG + M ist. Sie können diese entfernen, indem Sie sie durch einen sed-Befehl ersetzen. Dies macht im Wesentlichen das gleiche wie dos2unix
Cowboydan
11
In vim: :set fileformatGibt an, in welchem ​​von unixoder dosvim sich die Zeilenenden der Datei befinden. Sie können sie ändern, indem Sie :set fileformat=unix.
Victor Zamanian
5
Verwenden Sie das Flag -b, wenn Sie vi / vim starten, und verwenden Sie dann: set list, um die Endungen CR (^ M) und LF ($) anzuzeigen.
Samuel
1
@ RyanBerger - Sieht aus wie Sie ein -t vermissen. Es sollte sein od -t c file/path, aber danke für das neue Programm. Hat super funktioniert!
Eric Fossum
113

Ubuntu 14.04:

einfach cat -e <filename>funktioniert gut.

Dies zeigt Unix-Zeilenenden ( \noder LF) als $und Windows-Zeilenenden ( \r\noder CRLF) als an ^M$.

Alexander Shelemin
quelle
7
Funktioniert auch unter OSX. Gute Lösung. Einfach und funktionierte für mich, während die akzeptierte Antwort dies nicht tat. (Hinweis: war keine .txtDatei)
dlsso
4
Ist die Anzeige von M $ ein Osteregg / Windows-Bashing?
Tom M
Funktioniert nicht mit Solaris, aber der Mensch sagt, dass es hätte funktionieren sollen
Zeus
101

Versuchen Sie es in der Bash-Shell cat -v <filename>. Dies sollte Wagenrückläufe für Windows-Dateien anzeigen.

(Dies funktionierte bei mir in rxvt über Cygwin unter Windows XP).

Anmerkung des Herausgebers: cat -vVisualisiert \r(CR) Zeichen. als ^M. Somit werden Zeilenendsequenzen \r\nwie ^Mam Ende jeder Ausgabezeile angezeigt . cat -ewird zusätzlich visualisieren \n, nämlich als $. ( cat -etvisualisiert zusätzlich Tabulatorzeichen. as ^I.)

Kriegerpostbote
quelle
3
@ChrisK: Versuchen Sie echo -e 'abc\ndef\r\n' | cat -vund Sie sollten ein ^Mnach dem "def" sehen.
Bis auf weiteres angehalten.
Ich wollte sehen, ob die Datei ^ M (Windows / DOS EOL) hat und nur cat -v hat mir das gezeigt. +1 dafür
Ali
1
^ M = DOS / Windows-Stil
Mercury
Korrektur: Daher werden Zeilenendfolgen \ r \ n als ^ M $
Shayan
19

Es ist offen , CR als ^Mweniger nützlich anzuzeigen less -uoder -ueinmal weniger zu tippen .

man less sagt:

-u or --underline-special

      Causes backspaces and carriage returns to be treated  as  print-
      able  characters;  that  is,  they are sent to the terminal when
      they appear in the input.
P. Kucerak
quelle
1
Bitte klären Sie Ihre Antwort.
adao7000
12

Versuchen Sie es filedann file -kdanndos2unix -ih

filewird in der Regel genug sein. Aber für schwierige Fälle versuchen Sie es file -koder dosunix -ih.

Details unten.


Versuchen file -k

Kurzfassung: file -k somefile.txt wird es Ihnen sagen.

  • Es wird with CRLF line endingsfür DOS / Windows-Zeilenenden ausgegeben .
  • Es wird with LF line endingsfür MAC-Leitungsenden ausgegeben .
  • Und für die Linux / Unix-Zeile "CR" wird nur ausgegeben text. (Wenn also keine Art von explizit erwähnt wird, line endingsbedeutet dies implizit: "CR-Zeilenenden" .)

Langfassung siehe unten.


Beispiel aus der Praxis: Zertifikatcodierung

Ich muss dies manchmal auf PEM-Zertifikatdateien überprüfen.

Das Problem mit regulären fileist folgendes: Manchmal wird versucht, zu klug / zu spezifisch zu sein.

Versuchen wir ein kleines Quiz: Ich habe einige Dateien. Und eine dieser Dateien hat unterschiedliche Zeilenenden. Welcher?

(Übrigens: So sieht eines meiner typischen "Certificate Work" -Verzeichnisse aus.)

Versuchen wir es regelmäßig file:

$ file -- *
0.example.end.cer:         PEM certificate
0.example.end.key:         PEM RSA private key
1.example.int.cer:         PEM certificate
2.example.root.cer:        PEM certificate
example.opensslconfig.ini: ASCII text
example.req:               PEM certificate request

Huh. Es sagt mir nicht die Zeilenenden. Und ich wusste bereits , dass dies Zertifizierungsdateien waren. Ich brauchte keine "Datei", um mir das zu sagen.

Was können Sie noch versuchen?

Sie können es dos2unixmit dem --infoSchalter folgendermaßen versuchen :

$ dos2unix --info -- *
  37       0       0  no_bom    text    0.example.end.cer
   0      27       0  no_bom    text    0.example.end.key
   0      28       0  no_bom    text    1.example.int.cer
   0      25       0  no_bom    text    2.example.root.cer
   0      35       0  no_bom    text    example.opensslconfig.ini
   0      19       0  no_bom    text    example.req

Das sagt dir also: yup, "0.example.end.cer" muss der seltsame Mann sein. Aber welche Art von Zeilenenden gibt es? Kennen Sie das dos2unix-Ausgabeformat auswendig? (Ich nicht.)

Aber zum Glück gibt es die --keep-going(oder -kkurz gesagt) Option in file:

$ file --keep-going -- *
0.example.end.cer:         PEM certificate\012- , ASCII text, with CRLF line terminators\012- data
0.example.end.key:         PEM RSA private key\012- , ASCII text\012- data
1.example.int.cer:         PEM certificate\012- , ASCII text\012- data
2.example.root.cer:        PEM certificate\012- , ASCII text\012- data
example.opensslconfig.ini: ASCII text\012- data
example.req:               PEM certificate request\012- , ASCII text\012- data

Ausgezeichnet! Jetzt wissen wir, dass unsere ungerade Datei DOS ( CRLF) -Zeilenenden hat. (Und die anderen Dateien haben Unix ( LF) -Zeilenenden. Dies ist in dieser Ausgabe nicht explizit. Es ist implizit. Es ist genau so, wie es fileeine "normale" Textdatei erwartet.)

(Wenn Sie meine Mnemonik teilen möchten: "L" steht für "Linux" und für "LF".)

Lassen Sie uns nun den Täter bekehren und es erneut versuchen:

$ dos2unix -- 0.example.end.cer

$ file --keep-going -- *
0.example.end.cer:         PEM certificate\012- , ASCII text\012- data
0.example.end.key:         PEM RSA private key\012- , ASCII text\012- data
1.example.int.cer:         PEM certificate\012- , ASCII text\012- data
2.example.root.cer:        PEM certificate\012- , ASCII text\012- data
example.opensslconfig.ini: ASCII text\012- data
example.req:               PEM certificate request\012- , ASCII text\012- data  

Gut. Jetzt haben alle Zertifikate Unix-Zeilenenden.

Versuchen dos2unix -ih

Ich wusste das nicht, als ich das obige Beispiel schrieb, aber:

Tatsächlich stellt sich heraus, dass dos2unix Ihnen eine Kopfzeile gibt, wenn Sie -ih(kurz für --info=h) wie folgt verwenden :

$ dos2unix -ih -- *
 DOS    UNIX     MAC  BOM       TXTBIN  FILE
   0      37       0  no_bom    text    0.example.end.cer
   0      27       0  no_bom    text    0.example.end.key
   0      28       0  no_bom    text    1.example.int.cer
   0      25       0  no_bom    text    2.example.root.cer
   0      35       0  no_bom    text    example.opensslconfig.ini
   0      19       0  no_bom    text    example.req

Und noch ein "tatsächlicher" Moment: Das Header-Format ist wirklich leicht zu merken: Hier sind zwei Mnemoniken:

  1. Es ist DUMB (von links nach rechts: d für Dos, u für Unix, m für Mac, b für BOM).
  2. Und außerdem: "DUM" ist nur die alphabetische Reihenfolge von D, U und M.

Weiterführende Literatur

StackzOfZtuff
quelle
1
Es generiert eine Ausgabe wie: Accounts.java: Java source, ASCII text\012-unter Windows in MinTTY
Standalone
@standalone: ​​interessant. Ich habe seltsame Dinge über eine Option namens "igncr" gelesen - und was Sie sagen, klingt so. Kann aber nicht reproduzieren, was Sie beschreiben. (Ich habe versucht, in der Bash inside Mintty, die mit Git-for-Windows geliefert wird, "Git Version 2.24.0.windows.1".)
StackzOfZtuff
Hm, ich habe es file -k Accounts.javain der Münze versucht , die auch mit Git-for-Windows geliefert wird, aber meine Version istgit version 2.21.0.windows.1
Standalone
Arbeitslösung für mich istcat -e file_to_test
Standalone
9

Sie können xxdeinen Hex-Dump der Datei anzeigen und nach Zeichen "0d0a" oder "0a" suchen.

Sie können verwenden, cat -v <filename>wie @warriorpostman vorschlägt.

Reich
quelle
1
Es funktioniert bei mir mit cat v 8.23. Unix-Zeilenenden drucken keine zusätzlichen Informationen, DOS-Zeilenenden geben jedoch ein "^ M" aus.
Rich
Das muss das sein, worauf ich mit 8.21 stoße, da ich Unix-Zeilenenden verwende.
Neanderslob
5

Mit dem Befehl können Sie todos filenamein DOS-Endungen und fromdos filenamein UNIX-Zeilenenden konvertieren. Geben Sie Folgendes ein, um das Paket unter Ubuntu zu installieren sudo apt-get install tofrodos.

Zorayr
quelle
5

Sie können vim -b filenameeine Datei im Binärmodus bearbeiten, in der ^ M Zeichen für den Wagenrücklauf angezeigt werden. Eine neue Zeile zeigt an, dass LF vorhanden ist, und zeigt die Zeilenenden von Windows CRLF an. Mit LF meine ich \nund mit CR meine ich \r. Beachten Sie, dass bei Verwendung der Option -b die Datei standardmäßig immer im UNIX-Modus bearbeitet wird, wie [unix]in der Statuszeile angegeben. Wenn Sie also neue Zeilen hinzufügen, enden diese mit LF und nicht mit CRLF. Wenn Sie normales vim ohne -b für eine Datei mit CRLF-Zeilenenden verwenden, sollte [dos]dies in der Statuszeile angezeigt werden, und eingefügte Zeilen haben CRLF als Zeilenende. Die vim-Dokumentation zum fileformatsEinstellen erklärt die Komplexität.

Außerdem habe ich nicht genügend Punkte, um die Notepad ++ - Antwort zu kommentieren. Wenn Sie jedoch Notepad ++ unter Windows verwenden, verwenden Sie das Menü Ansicht / Symbol anzeigen / Zeilenende anzeigen, um CR und LF anzuzeigen. In diesem Fall wird LF angezeigt, während für vim der LF durch eine neue Zeile angezeigt wird.

smalers
quelle
0

Ich speichere meine Ausgabe in eine Textdatei. Ich öffne es dann in Notepad ++ und klicke dann auf die Schaltfläche Alle Zeichen anzeigen. Nicht sehr elegant, aber es funktioniert.

Diego
quelle
3
Diese Frage ist als Linux markiert und ich glaube nicht, dass Notepad ++ für Linux ist. Dies sollte jedoch für Windows funktionieren.
Rick Smith
0

Vim - Windows-Zeilenumbrüche immer als anzeigen ^M

Wenn Sie es vorziehen, die Windows-Zeilenumbrüche in vim render as immer als anzuzeigen ^M, können Sie diese Zeile zu Ihrem hinzufügen .vimrc:

set ffs=unix

Dadurch interpretiert vim jede geöffnete Datei als Unix-Datei. Da Unix-Dateien \ndas Zeilenumbruchzeichen haben, wird eine Windows-Datei mit dem Zeilenumbruchzeichen \r\n(dank \n) weiterhin ordnungsgemäß gerendert, jedoch ^Mam Ende der Datei (so rendert vim das \rZeichen).


Vim - zeigt manchmal Windows-Zeilenumbrüche an

Wenn Sie es vorziehen, es nur pro Datei festzulegen, können Sie es :e ++ff=unixbeim Bearbeiten einer bestimmten Datei verwenden.


Vim - zeige immer den Dateityp ( unixvs dos)

Wenn Sie in der unteren Zeile von Vim immer angezeigt werden soll , was Sie bearbeiten , Dateityp (und Sie nicht den Dateityp auf Unix eingestellte Kraft) können Sie Ihre hinzufügen statuslinemit
set statusline+=\ %{&fileencoding?&fileencoding:&encoding}.

Meine vollständige Statuszeile finden Sie unten. Fügen Sie es einfach zu Ihrem hinzu .vimrc.

" Make statusline stay, otherwise alerts will hide it
set laststatus=2
set statusline=
set statusline+=%#PmenuSel#
set statusline+=%#LineNr#
" This says 'show filename and parent dir'
set statusline+=%{expand('%:p:h:t')}/%t
" This says 'show filename as would be read from the cwd'
" set statusline+=\ %f
set statusline+=%m\
set statusline+=%=
set statusline+=%#CursorColumn#
set statusline+=\ %y
set statusline+=\ %{&fileencoding?&fileencoding:&encoding}
set statusline+=\[%{&fileformat}\]
set statusline+=\ %p%%
set statusline+=\ %l:%c
set statusline+=\ 

Es wird wie rendern

.vim/vimrc\                                    [vim] utf-8[unix] 77% 315:6

am Ende Ihrer Datei


Vim - manchmal Dateityp anzeigen ( unixvs dos)

Wenn Sie nur sehen möchten, welchen Dateityp Sie haben, können Sie ihn verwenden :set fileformat(dies funktioniert nicht, wenn Sie den Dateityp zwangsweise festgelegt haben). Es wird unixfür Unix-Dateien und dosfür Windows zurückgegeben.

jeremysprofile
quelle