Eliminar CRLF

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
CRLFcomo^M::e ++ff=unix. - Sustituir todos los
^Mpor^N::s/\r/\r/. - Quitar
^Msolo 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.
Descarga e instala Tofrodos, disponible en el AUR. (O
dos2unixdecommunity)Ejecuta este comando en la carpeta que va al control de versiones (donde
^MesCtrl+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).
Links

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! 🙂