Eliminar CRLF

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

Para mantener el estándar usado en los antiguos Teletipos, DOS/Windows utiliza dos caracteres de control para representar un salto de línea: un Carriage Return (CR = 0x0D) y un Line Feed (LF = 0x0A). Los sistemas tipo Unix se dieron cuenta de que eso desperdicia 1 byte por línea y que basta con un LF para representar una nueva línea.

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

Observa que el archivo creado en Windows contiene la secuencia 0d 0a donde el creado en Linux tiene solo 0a. Esto trae problemas de compatibilidad y dolores de cabeza.

Aunque buenos editores consiguen trabajar con ambos (en Notepad las líneas de bacon_linux.txt aparecerán concatenadas), archivos que supuestamente deberían ser iguales aparecen como diferentes 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 puse en control de versiones algunos códigos hechos en parte en Windows y parte en Linux y preferí estandarizar todo a LF. Aquí muestro cómo hice la conversión automáticamente en 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 teclea 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 uno de los utilitarios de línea para procesar texto más útiles.

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

Cuidado: si el archivo ya está en formato Unix, terminarás borrando el último carácter de cada línea.

La conversión contraria (a DOS) también puede hacerse con GNU sed:

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

Tofrodos

Si no quieres preocuparte en verificar si el archivo ya sigue el estándar Unix, una alternativa a sed es Tofrodos. Si el archivo ya está convertido, lo deja tal cual; es especialmente útil en scripts.

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

  2. Ejecuta el siguiente comando en la carpeta que irá 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 a LF en todos los archivos de la carpeta actual y subcarpetas.

Cambia fromdos por todos para convertir en sentido contrario (LF a CR+LF).


Enlaces

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