¿Cómo encontrar los finales de línea en un archivo de texto?


304

Estoy tratando de usar algo en bash para mostrarme los finales de línea en un archivo impreso en lugar de interpretado. El archivo es un volcado de SSIS / SQL Server que está siendo leído por una máquina Linux para su procesamiento.

  • ¿Hay interruptores dentro vi, less, more, etc?

  • Además de ver los finales de línea, necesito saber qué tipo de final de línea es ( CRLFo LF). ¿Cómo lo descubro?


1
Sugerencia general: si tiene una idea de qué comando * nix / cygwin podría usar, siempre puede ver su página de manual para buscar los interruptores que podrían darle la funcionalidad que necesita. Ej man less.
David Rivers

Respuestas:


421

Puede usar la fileutilidad para darle una indicación del tipo de terminaciones de línea.

Unix:

$ file testfile1.txt
testfile.txt: ASCII text

"DOS":

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

Para convertir de "DOS" a Unix:

$ dos2unix testfile2.txt

Para convertir de Unix a "DOS":

$ unix2dos testfile1.txt

La conversión de un archivo ya convertido no tiene ningún efecto, por lo que es seguro ejecutarlo a ciegas (es decir, sin probar primero el formato), aunque se aplican las exenciones de responsabilidad habituales, como siempre.


99
Estos a veces se denominan "fromdos" y "todos", respectivamente (como es el caso en Ubuntu 10.4+)
Jess Chadwick

3
@JessChadwick: Sí, pero solo si instala explícitamente el tofrodospaquete con sudo apt-get install tofrodos, tal como tendría que ejecutar sudo apt-get install dos2unixpara obtener dos2unixy unix2dos.
mklement0

Actully dos2unix no puede hacer todo el trabajo, creo que stackoverflow.com/questions/23828554/dos2unix-doesnt-convert-m da la mejor respuesta
nathan

@nathan: ¿En qué dos2unixfalla? El OP en esa pregunta solo describe vagamente el problema.
Pausado hasta nuevo aviso.

El comando de archivo @DennisWilliamson antes y después del comando dos2unix obtuvo el mismo resultado: fuente xxx.c C, texto ASCII, con terminadores de línea CR, LF. Encontré que este archivo c tiene ^ M en el medio de la línea que le gusta xxxxxxx ^ M xxxxxxx
nathan

127

En vi...

:set list para ver los finales de línea.

:set nolist para volver a la normalidad

Si bien no creo que pueda ver \nni \r\ndentro vi, puede ver qué tipo de archivo es (UNIX, DOS, etc.) para inferir qué terminaciones de línea tiene ...

:set ff

Alternativamente, desde bashpuede usar od -t c <filename>o simplemente od -c <filename>para mostrar las devoluciones.


26
Desafortunadamente, no creo que vi pueda mostrar esos caracteres específicos. Puede probar od -c <nombre de archivo> que creo que mostrará \ n o \ r \ n.
Ryan Berger el

3
En la categoría "por lo que vale", puede grep para el estilo Dos CRLF emitiendo grep --regex = "^ M" donde ^ M es CTRL + V CTRL + M. Puede eliminarlos reemplazándolos con un comando sed. Esto hace esencialmente lo mismo que dos2unix
cowboydan

11
En vim: :set fileformatinformará en cuál unixo dosvim cree que están las terminaciones de línea del archivo. Puede cambiarlo por :set fileformat=unix.
Victor Zamanian

55
Use el indicador -b al iniciar vi / vim y luego use: set list para ver las terminaciones CR (^ M) y LF ($).
Samuel

1
@RyanBerger - Parece que te falta un -t. Debería serlo od -t c file/path, pero gracias por el nuevo programa. Funcionó genial!
Eric Fossum

113

Ubuntu 14.04:

simple cat -e <filename>funciona bien.

Esto muestra los finales de línea de Unix ( \no LF) como $y los finales de línea de Windows ( \r\no CRLF) como ^M$.


77
También funciona en OSX. Buena solución. Simple y funcionó para mí, mientras que la respuesta aceptada no. (Nota: no era un .txtarchivo)
dlsso

44
¿Es la exhibición de M $ an easteregg / windows bashing?
Tom M

No funciona con Solaris, pero el hombre dice que debería haber funcionado
Zeus

101

En el shell bash, inténtalo cat -v <filename>. Esto debería mostrar retornos de carro para archivos de Windows.

(Esto funcionó para mí en rxvt a través de Cygwin en Windows XP).

Nota del editor: cat -vvisualiza \rcaracteres (CR). como ^M. Por lo tanto, las \r\nsecuencias de final de línea se mostrarán como ^Mal final de cada línea de salida. cat -evisualizará adicionalmente \n, es decir, como $. ( cat -ettambién visualizará caracteres de tabulación. como ^I.)


3
@ChrisK: Inténtalo echo -e 'abc\ndef\r\n' | cat -vy deberías ver un ^Mdespués de "def".
Pausado hasta nuevo aviso.

Quería ver si el archivo tiene ^ M (EOL de Windows / DOS) y solo cat -v me mostró eso. +1 por eso
Ali

1
^ M = estilo DOS / Windows
Mercury

corrección: Por lo tanto, las secuencias \ r \ n de final de línea se mostrarán como ^ M $
Shayan

19

Para mostrar CR como ^Mde menor uso less -uo escriba -uuna vez menos está abierto.

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
Por favor aclare su respuesta.
adao7000

12

Intenta fileentonces file -kentoncesdos2unix -ih

filePor lo general, será suficiente. Pero para casos difíciles intente file -ko dosunix -ih.

Detalles abajo.


Tratar file -k

Versión corta: file -k somefile.txt te lo diré.

  • Saldrá with CRLF line endingspara las terminaciones de línea de DOS / Windows.
  • Saldrá with LF line endingspara las terminaciones de línea MAC.
  • Y para la línea "CR" de Linux / Unix solo saldrá text. (Entonces, si no menciona explícitamente ningún tipo de line endingsesto, esto significa implícitamente: "terminaciones de línea CR" ).

Versión larga ver abajo.


Ejemplo del mundo real: codificación de certificados

A veces tengo que verificar esto para archivos de certificado PEM.

El problema con regular filees este: a veces está tratando de ser demasiado inteligente / demasiado específico.

Probemos un pequeño cuestionario: tengo algunos archivos. Y uno de estos archivos tiene diferentes finales de línea. ¿Cúal?

(Por cierto: así es como se ve uno de mis directorios típicos de "trabajo de certificado").

Probemos con regularidad 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 No me dice los finales de línea. Y ya sabía que esos eran archivos cert. No necesitaba "archivo" para decirme eso.

¿Qué más puedes probar?

Puede intentar dos2unixcon el --infointerruptor de esta manera:

$ 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

Eso te dice que: sí, "0.example.end.cer" debe ser el hombre extraño. Pero, ¿qué tipo de terminaciones de línea hay? Qué se conoce el formato de salida dos2unix de memoria? (Yo no.)

Pero afortunadamente existe la opción --keep-going(o -kpara abreviar) en 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

¡Excelente! Ahora sabemos que nuestro archivo impar tiene CRLFterminaciones de línea DOS ( ). (Y los otros archivos tienen LFterminaciones de línea Unix ( ). Esto no es explícito en esta salida. Es implícito. Es justo como se fileespera que sea un archivo de texto "normal").

(Si quieres compartir mi mnemotécnico: "L" es para "Linux" y para "LF").

Ahora convierta al culpable e intente nuevamente:

$ 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  

Bueno. Ahora todos los certs tienen terminaciones de línea Unix.

Tratar dos2unix -ih

No sabía esto cuando estaba escribiendo el ejemplo anterior, pero:

En realidad, resulta que dos2unix le dará una línea de encabezado si usa -ih(abreviatura de --info=h) así:

$ 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

Y otro momento "en realidad": el formato del encabezado es realmente fácil de recordar: aquí hay dos mnemotécnicos:

  1. Es DUMB (de izquierda a derecha: d para Dos, u para Unix, m para Mac, b para BOM).
  2. Y también: "DUM" es solo el orden alfabético de D, U y M.

Otras lecturas


1
Genera resultados como: Accounts.java: Java source, ASCII text\012-en Windows en MinTTY
independiente

@standalone: ​​interesante. He leído cosas raras sobre una opción llamada "igncr", y lo que estás diciendo suena así. Pero no puedo reproducir lo que describe. (Lo intenté dentro del Bash inside mintty que viene con Git-for-Windows, "git versión 2.24.0.windows.1".)
StackzOfZtuff

Hm, intenté file -k Accounts.javadentro del mintty que viene con git-for-windows también, pero mi versión esgit version 2.21.0.windows.1
independiente

La solución de trabajo para mí escat -e file_to_test
solo

9

Puede usar xxdpara mostrar un volcado hexadecimal del archivo y buscar caracteres "0d0a" o "0a".

Puedes usar cat -v <filename>como sugiere @warriorpostman.


1
A mí me funciona con cat v 8.23. Los finales de línea de Unix no imprimirán ninguna información adicional, pero los finales de línea de DOS imprimirán una "^ M".
Rico

Eso debe ser con lo que me encuentro con 8.21, dado el hecho de que estoy usando terminaciones de línea unix.
neanderslob

5

Puede usar el comando todos filenamepara convertir a finales de DOS y fromdos filenamepara convertir a finales de línea UNIX. Para instalar el paquete en Ubuntu, escriba sudo apt-get install tofrodos.


5

Puede usar vim -b filenamepara editar un archivo en modo binario, que mostrará ^ M caracteres para el retorno de carro y una nueva línea es indicativa de que LF está presente, lo que indica las terminaciones de línea CRLF de Windows. Por LF quiero decir \ny por CR quiero decir \r. Tenga en cuenta que cuando usa la opción -b, el archivo siempre se editará en modo UNIX de manera predeterminada, como se indica [unix]en la línea de estado, lo que significa que si agrega nuevas líneas terminarán con LF, no CRLF. Si usa vim normal sin -b en un archivo con terminaciones de línea CRLF, debería ver que se [dos]muestra en la línea de estado y las líneas insertadas tendrán CRLF como final de línea. La documentación de vim para la fileformatsconfiguración explica las complejidades.

Además, no tengo suficientes puntos para comentar sobre la respuesta de Notepad ++, pero si usa Notepad ++ en Windows, use el menú Ver / Mostrar símbolo / Mostrar final de línea para mostrar CR y LF. En este caso, se muestra LF, mientras que para vim, LF se indica mediante una nueva línea.


0

Volcado mi salida a un archivo de texto. Luego lo abro en notepad ++ y luego hago clic en el botón mostrar todos los caracteres. No es muy elegante pero funciona.


3
Esta pregunta está etiquetada como Linux y no creo que notepad ++ sea para Linux. Sin embargo, esto debería funcionar para Windows.
Rick Smith

0

Vim: siempre muestra las nuevas líneas de Windows como ^M

Si prefiere ver siempre las nuevas líneas de Windows en vim render as ^M, puede agregar esta línea a su .vimrc:

set ffs=unix

Esto hará que vim interprete cada archivo que abra como un archivo Unix. Dado que los archivos Unix tienen \ncomo carácter de nueva línea, un archivo de Windows con un carácter de nueva línea de \r\ntodavía se representará correctamente (gracias a \n) pero tendrá ^Mal final del archivo (que es cómo vim representa el \rcarácter).


Vim: a veces muestra nuevas líneas de Windows

Si prefiere configurarlo por archivo, puede usarlo :e ++ff=unixal editar un archivo determinado.


Vim: siempre muestra el tipo de archivo ( unixvs dos)

Si desea que la línea inferior de vim muestre siempre qué tipo de archivo está editando (y no forzó a establecer el tipo de archivo en unix), puede agregarlo a su statuslinecon
set statusline+=\ %{&fileencoding?&fileencoding:&encoding}.

Mi línea de estado completa se proporciona a continuación. Solo agrégalo a tu .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+=\ 

Se renderizará como

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

al final de tu archivo


Vim: a veces muestra el tipo de archivo ( unixvs dos)

Si solo quieres ver qué tipo de archivo tienes, puedes usarlo :set fileformat(esto no funcionará si forzaste a establecer el tipo de archivo). Volverá unixpara archivos Unix y dospara Windows.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.