Eliminar CRLF

abr 23, 2012·
Julio Batista Silva
Julio Batista Silva
· 5 min de lectura
blog Linux

Para mantener el estándar de los antiguos teletipos, DOS/Windows usa dos caracteres de control para representar un salto de línea, un Carriage Return (CR = 0x0D) y un Line Feed (LF = 0x0A); pero los sistemas tipo Unix vieron que era desperdiciar 1 byte por línea y que bastaba un LF para representar una línea nueva.

Ejemplo:

$ cat bacon.txt
Bacon Ipsum:

Bacon ipsum dolor sit amet salami
pork belly tail tongue pancetta,
pork loin tri-tip drumstick bresaola shankle.
$ file bacon_windows.txt bacon_linux.txt
bacon_windows.txt: ASCII text, with CRLF line terminators
bacon_linux.txt:   ASCII text
$ hexdump -C bacon_linux.txt
00000000  42 61 63 6f 6e 20 49 70  73 75 6d 3a <strong>0a 0a</strong> 42 61  |Bacon Ipsum:..Ba|
00000010  63 6f 6e 20 69 70 73 75  6d 20 64 6f 6c 6f 72 20  |con ipsum dolor |
00000020  73 69 74 20 61 6d 65 74  20 73 61 6c 61 6d 69 <strong>0a</strong>  |sit amet salami.|
00000030  70 6f 72 6b 20 62 65 6c  6c 79 20 74 61 69 6c 20  |pork belly tail |
00000040  74 6f 6e 67 75 65 20 70  61 6e 63 65 74 74 61 2c  |tongue pancetta,|
00000050  <strong>0a</strong> 70 6f 72 6b 20 6c 6f  69 6e 20 74 72 69 2d 74  |.pork loin tri-t|
00000060  69 70 20 64 72 75 6d 73  74 69 63 6b 20 62 72 65  |ip drumstick bre|
00000070  73 61 6f 6c 61 20 73 68  61 6e 6b 6c 65 2e <strong>0a</strong>     |saola shankle..|
0000007f
$ hexdump -C bacon_windows.txt
00000000  42 61 63 6f 6e 20 49 70  73 75 6d 3a <strong>0d 0a 0d 0a</strong>  |Bacon Ipsum:....|
00000010  42 61 63 6f 6e 20 69 70  73 75 6d 20 64 6f 6c 6f  |Bacon ipsum dolo|
00000020  72 20 73 69 74 20 61 6d  65 74 20 73 61 6c 61 6d  |r sit amet salam|
00000030  69 <strong>0d 0a</strong> 70 6f 72 6b 20  62 65 6c 6c 79 20 74 61  |i..pork belly ta|
00000040  69 6c 20 74 6f 6e 67 75  65 20 70 61 6e 63 65 74  |il tongue pancet|
00000050  74 61 2c <strong>0d 0a</strong> 70 6f 72  6b 20 6c 6f 69 6e 20 74  |ta,..pork loin t|
00000060  72 69 2d 74 69 70 20 64  72 75 6d 73 74 69 63 6b  |ri-tip drumstick|
00000070  20 62 72 65 73 61 6f 6c  61 20 73 68 61 6e 6b 6c  | bresaola shankl|
00000080  65 2e <strong>0d 0a</strong>                                       |e...|
00000084

Fíjate en que el archivo creado en Windows contiene la secuencia 0d 0a donde el creado en Linux solo tiene 0a. Está claro que eso iba a traer problemas de compatibilidad y dolores de cabeza.

Aunque los buenos editores manejan los dos formatos (en el Notepad las líneas de bacon_linux.txt aparecen todas seguidas), archivos que en teoría deberían ser iguales salen como distintos si usamos herramientas como “diff”:

$ diff bacon_windows.txt bacon_linux.txt
1,5c1,5
< Bacon Ipsum:
<
< Bacon ipsum dolor sit amet salami
< pork belly tail tongue pancetta,
< pork loin tri-tip drumstick bresaola shankle.
---
> Bacon Ipsum:
>
> Bacon ipsum dolor sit amet salami
> pork belly tail tongue pancetta,
> pork loin tri-tip drumstick bresaola shankle.

Hoy he puesto bajo control de versiones algo de código escrito en parte en Windows y en parte en Linux, y preferí unificarlo todo con LF. Aquí muestro cómo hice la conversión automáticamente desde Linux:

Vim

Dos formas:

1

  • Mostrar CRLF como ^M: :e ++ff=unix.
  • Sustituir todos los ^M por ^N: :s/\r/\r/.
  • Quitar ^M solo si está al final de la línea: :s/\r\+$//
  • Quitar todos los ^M: :s/^M//

^M se escribe como ^V^M (ctrl+V ctrl+M).

2

  • Convertir el formato del archivo a unix: :setlocal fileformat=unix
  • Guardar: :w
  • Recargar: :e

Convertir varios archivos

  • Asume formato DOS: :set ffs=dos.
  • Lista de archivos a convertir: :args *.c *.h.
  • Cambia el formato de cada argumento: :argdo set ff=unix|w.

Otros comandos útiles: :set list y :set nobomb.

sed

sed, Stream EDitor, es una de las utilidades de línea de comandos más útiles para procesar texto.

Trabaja línea a línea, así que, si sabemos que el archivo está en formato DOS, podemos usar sed para sustituir los dos últimos caracteres (CRLF = /r/n) de cada línea por solo LF (/n):

sed -i 's/.$//' archivo.txt

Pero cuidado: si el archivo ya está en formato Unix acabarás borrando el último carácter de cada línea.

El camino inverso, convertir un archivo al formato DOS, también se puede hacer con GNU sed:

sed -i 's/$/\r/' archivo.txt

Tofrodos

Si no quieres tener que comprobar si el archivo ya sigue el formato Unix, una alternativa a sed es Tofrodos. Si el archivo ya está convertido, simplemente lo deja como está, algo especialmente útil en scripts.

  1. Descarga e instala Tofrodos, disponible en el AUR. (O dos2unix de community)

  2. Ejecuta este comando en la carpeta que va al control de versiones (donde ^M es Ctrl+V + Ctrl+M):

    grep -IUrl --color '^M' . | xargs -ifile fromdos 'file'
    

Este comando convertirá todos los CR+LF en LF en todos los archivos de la carpeta actual y de sus subcarpetas.

Cambia fromdos por todos para hacer la conversión contraria (LF a CR+LF).


Julio Batista Silva
Autores
Senior Cloud Developer

Soy un ingeniero informático brasileño radicado en Alemania, apasionado por la tecnología, la ciencia, la fotografía y los idiomas.

Llevo programando cerca de dos décadas, explorando desde apps móviles y desarrollo web hasta aprendizaje automático. Hoy me enfoco en SRE en la nube e ingeniería de datos.

Soy voluntario en las comunidades de open source y Python, ayudando a organizar PyCon DE y PyData Berlin, dando mentorías y contribuyendo con código y traducciones.

En mi blog comparto consejos de Linux, guías de configuración y notas personales que escribí como referencia futura. Espero que también sean útiles para otras personas. El contenido está disponible en varios idiomas.

Visita mi galería para ver algunas de mis fotografías.

Fuera del teclado, me encontrarás en conciertos, tocando el clarinete, en bicicleta, buceando o explorando nuevos lugares, culturas y cocinas.

¡Siempre feliz de conectar! 🙂

comments powered by Disqus