Eliminar CRLF

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
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 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.
Descarga e instala Tofrodos, disponible en el AUR. (O
dos2unixdecommunity)Ejecuta el siguiente comando en la carpeta que irá al control de versiones (donde
^MesCtrl+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).