Come scoprire le terminazioni di riga in un file di testo?


304

Sto cercando di usare qualcosa in bash per mostrarmi le terminazioni di riga in un file stampato anziché interpretato. Il file è un dump da SSIS / SQL Server che viene letto da una macchina Linux per l'elaborazione.

  • Ci sono gli switch vi, less, more, ecc?

  • Oltre a vedere i finali, devo sapere che tipo di fine è ( CRLFo LF). Come lo scopro?


1
Suggerimento generale: se hai idea di quale comando * nix / cygwin potresti usare, puoi sempre visualizzare la sua pagina man per cercare opzioni che potrebbero darti le funzionalità di cui hai bisogno. Ad es man less.
David Rivers,

Risposte:


421

È possibile utilizzare l' fileutilità per fornire un'indicazione del tipo di terminazioni di riga.

Unix:

$ file testfile1.txt
testfile.txt: ASCII text

"DOS":

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

Per convertire da "DOS" a Unix:

$ dos2unix testfile2.txt

Per convertire da Unix a "DOS":

$ unix2dos testfile1.txt

La conversione di un file già convertito non ha alcun effetto, quindi è sicuro eseguire alla cieca (cioè senza testare prima il formato) anche se si applicano le solite dichiarazioni di non responsabilità, come sempre.


9
Questi sono ora talvolta chiamati "fromdos" e "todos", rispettivamente (come nel caso di Ubuntu 10.4+)
Jess Chadwick,

3
@JessChadwick: Sì, ma solo se installi esplicitamente il tofrodospacchetto con sudo apt-get install tofrodos- proprio come dovresti correre sudo apt-get install dos2unixper ottenere dos2unixe unix2dos.
mklement0

In realtà dos2unix non può fare tutto il lavoro, penso che stackoverflow.com/questions/23828554/dos2unix-doesnt-convert-m dà la migliore risposta
nathan

@nathan: cosa dos2unixfallisce? L'OP a quella domanda descrive solo vagamente il problema.
In pausa fino a ulteriore avviso.

Il comando di file @DennisWilliamson prima e dopo il comando dos2unix ha ottenuto lo stesso output: sorgente xxx.c C, testo ASCII, con terminatori di riga CR, LF. Ho trovato che questo file c ha ^ M nel mezzo della riga a cui piace xxxxxxx ^ M xxxxxxx
nathan

127

In vi...

:set list per vedere le terminazioni di riga.

:set nolist per tornare alla normalità.

Anche se non credo che si può vedere \no \r\nin vi, è possibile vedere che tipo di file è (UNIX, DOS, ecc) per dedurre che la fine della riga che ha ...

:set ff

In alternativa, da bashte puoi usare od -t c <filename>o semplicemente od -c <filename>per visualizzare i resi.


26
Sfortunatamente, non penso che vi possa mostrare quei personaggi specifici. Puoi provare od -c <nomefile> che credo mostrerà \ n o \ r \ n.
Ryan Berger,

3
Nella categoria "per quello che vale" puoi grep per CRLF in stile Dos emettendo grep --regex = "^ M" dove ^ M è CTRL + V CTRL + M. Puoi rimuoverli sostituendo quelli con un comando sed. Questo fa essenzialmente la stessa cosa di dos2unix
cowboydan

11
In vim: :set fileformatsegnalerà quale unixo dosvim pensa che siano presenti le terminazioni di riga del file. Puoi cambiarlo di :set fileformat=unix.
Victor Zamanian,

5
Usa il flag -b quando avvii vi / vim e poi usa: set list per vedere i finali CR (^ M) e LF ($).
Samuel,

1
@RyanBerger - Sembra che ti manchi un -t. Dovrebbe essere od -t c file/path, ma grazie per il nuovo programma. Ha funzionato alla grande!
Eric Fossum,

113

Ubuntu 14.04:

le cat -e <filename>opere semplici vanno bene.

Questo mostra i finali di linea Unix ( \no LF) come $e i finali di linea Windows ( \r\no CRLF) come ^M$.


7
Funziona anche su OSX. Buona soluzione Semplice e ha funzionato per me, mentre la risposta accettata no. (Nota: non era un .txtfile)
dlsso,

4
è il display di M $ un easteregg / windows bashing?
Tom M,

Non funziona con Solaris, ma l'uomo dice che avrebbe dovuto funzionare
Zeus

101

Nella shell bash, prova cat -v <filename>. Questo dovrebbe visualizzare i ritorni a capo per i file di Windows.

(Questo ha funzionato per me in rxvt tramite Cygwin su Windows XP).

Nota del redattore: cat -vvisualizza i caratteri \r(CR). come ^M. Pertanto, le \r\nsequenze di fine riga verranno visualizzate ^Malla fine di ogni riga di output. cat -evisualizzerà inoltre \n, vale a dire come $. ( cat -etvisualizzerà inoltre i caratteri di tabulazione. come ^I.)


3
@ChrisK: prova echo -e 'abc\ndef\r\n' | cat -ve dovresti vedere un ^Mdopo il "def".
In pausa fino a ulteriore avviso.

Volevo vedere se il file ha ^ M (Windows / DOS EOL) e solo cat -v me lo ha mostrato. +1 per quello
Ali

1
^ M = stile DOS / Windows
Mercury

correzione: Pertanto, le sequenze di fine riga verranno visualizzate come ^ M $
Shayan il

19

Per mostrare CR come ^Min meno utilizzare less -uo digitare -uuna volta meno è aperto.

man less dice:

-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.

1
Per favore chiarisci la tua risposta.
adao7000,

12

Prova fileallora file -kpoidos2unix -ih

filesarà di solito abbastanza. Ma per i casi difficili provare file -ko dosunix -ih.

Dettagli sotto.


Provare file -k

Versione breve: te file -k somefile.txt lo dirò.

  • Verrà emesso with CRLF line endingsper terminazioni di riga DOS / Windows.
  • Verrà emesso with LF line endingsper terminazioni di linea MAC.
  • E per la linea Linux / Unix "CR" verrà semplicemente emesso text. (Quindi, se non menziona esplicitamente alcun tipo di line endingsciò, ciò significa implicitamente: "terminazioni di riga CR" .)

Versione lunga vedi sotto.


Esempio reale: codifica certificati

A volte devo controllare questo per i file di certificato PEM.

Il problema con i regolari fileè questo: a volte sta cercando di essere troppo intelligente / troppo specifico.

Proviamo un piccolo quiz: ho alcuni file. E uno di questi file ha terminazioni di linea diverse. Quale?

(A proposito: ecco come appare una delle mie tipiche directory "lavoro certificato".)

Proviamo regolarmente 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. Non mi sta dicendo i finali. E sapevo già che quelli erano file di certificati. Non avevo bisogno di "file" per dirmelo.

Cos'altro puoi provare?

Potresti provare dos2unixcon l' --infointerruttore in questo modo:

$ 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

Quindi questo ti dice che: yup, "0.example.end.cer" deve essere l'uomo strano. Ma che tipo di terminazioni di linea ci sono? Non si conosce il formato di output dos2unix dal cuore? (Io non.)

Ma per fortuna c'è l' opzione --keep-going(o -kin breve) 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

Eccellente! Ora sappiamo che il nostro file dispari ha CRLFterminazioni di riga DOS ( ). (E gli altri file hanno LFterminazioni di riga Unix ( ). Questo non è esplicito in questo output. È implicito. È solo il modo in cui si fileaspetta un file di testo "normale".)

(Se vuoi condividere il mio mnemonico: "L" è per "Linux" e per "LF".)

Ora convertiamo il colpevole e riproviamo:

$ 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  

Buona. Ora tutte le certs hanno terminazioni di linea Unix.

Provare dos2unix -ih

Non lo sapevo quando stavo scrivendo l'esempio sopra ma:

In realtà risulta che dos2unix ti darà una riga di intestazione se usi -ih(abbreviazione di --info=h) in questo modo:

$ 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

E un altro momento "reale": il formato dell'intestazione è davvero facile da ricordare: ecco due mnemonici:

  1. È DUMB (da sinistra a destra: d per Dos, u per Unix, m per Mac, b per BOM).
  2. E anche: "DUM" è solo l'ordinamento alfabetico di D, U e M.

Ulteriori letture


1
Genera output come: Accounts.java: Java source, ASCII text\012-su Windows in MinTTY
stand alone

@standalone: ​​interessante. Ho letto cose strane su un'opzione chiamata "igncr" - e quello che stai dicendo suona così. Ma non riesco a riprodurre ciò che descrivi. (Ho provato all'interno di Bash all'interno di Mintty che viene fornito con Git-for-Windows, "versione git 2.24.0.windows.1".)
StackzOfZtuff

Hm, ho provato anche file -k Accounts.javanel gint che viene fornito con git-for-windows, ma la mia versione ègit version 2.21.0.windows.1
stand alone

La soluzione di lavoro per me ècat -e file_to_test
stand alone

9

È possibile utilizzare xxdper mostrare un dump esadecimale del file e cercare caratteri "0d0a" o "0a".

Puoi usare cat -v <filename>come suggerisce @warriorpostman.


1
Funziona per me con cat v 8.23. Le terminazioni di riga Unix non stamperanno ulteriori informazioni, ma le terminazioni di riga DOS stamperanno una "^ M".
Ricco

Dev'essere quello in cui mi imbatto con 8.21, dato che sto usando un finale di linea unix.
neanderslob,

5

È possibile utilizzare il comando todos filenameper convertire in finali DOS e fromdos filenameper convertire in finali di linea UNIX. Per installare il pacchetto su Ubuntu, digitare sudo apt-get install tofrodos.


5

È possibile utilizzare vim -b filenameper modificare un file in modalità binaria, che mostrerà ^ M caratteri per il ritorno a capo e una nuova riga indica la presenza di LF, che indica la fine della riga CRLF di Windows. Per LF intendo \ne per CR intendo \r. Si noti che quando si utilizza l'opzione -b, il file verrà sempre modificato in modalità UNIX per impostazione predefinita, come indicato dalla [unix]riga di stato, il che significa che se si aggiungono nuove righe, termineranno con LF, non CRLF. Se usi vim normale senza -b su un file con terminazioni di riga CRLF, dovresti vedere [dos]mostrato nella riga di stato e le righe inserite avranno CRLF come fine riga. La documentazione di vim per l' fileformatsimpostazione spiega le complessità.

Inoltre, non ho abbastanza punti per commentare la risposta di Notepad ++, ma se usi Notepad ++ su Windows, usa il menu Visualizza / Mostra simbolo / Mostra fine linea per visualizzare CR e LF. In questo caso viene mostrato LF mentre per Vim l'LF è indicato da una nuova riga.


0

Ho scaricato il mio output in un file di testo. Lo apro in Notepad ++, quindi faccio clic sul pulsante Mostra tutti i caratteri. Non molto elegante ma funziona.


3
Questa domanda è taggata come Linux e non credo che notepad ++ sia per linux. Questo dovrebbe funzionare per Windows però.
Rick Smith,

0

Vim: mostra sempre le nuove righe di Windows come ^M

Se si preferisce vedere sempre le newline di Windows in vim render as ^M, è possibile aggiungere questa riga a .vimrc:

set ffs=unix

Ciò consentirà a vim di interpretare ogni file che apri come file unix. Poiché i file unix hanno \ncome carattere di nuova riga, un file di Windows con un carattere di nuova riga \r\nverrà comunque visualizzato correttamente (grazie al \n) ma avrà ^Malla fine del file (che è il modo in cui vim rende il \rcarattere).


Vim - a volte mostra le nuove righe di Windows

Se preferisci impostarlo solo per file, puoi usarlo :e ++ff=unixquando modifichi un determinato file.


Vim - mostra sempre il tipo di file ( unixvs dos)

Se si desidera che la linea di fondo di vim per visualizzare sempre ciò che si sta modificando filetype (e non hai forza di impostare il tipo di file per UNIX) è possibile aggiungere al vostro statuslinecon
set statusline+=\ %{&fileencoding?&fileencoding:&encoding}.

Il mio statusline completo è fornito di seguito. Aggiungilo al tuo .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+=\ 

Renderà come

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

nella parte inferiore del file


Vim - a volte mostra il tipo di file ( unixvs dos)

Se vuoi solo vedere che tipo di file hai, puoi usare :set fileformat(questo non funzionerà se hai forzato l'impostazione del tipo di file). Tornerà unixper i file unix e dosper Windows.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.