Solución:
Los separadores de línea y los terminadores de línea han sido una fuente de fricción de compatibilidad entre sistemas desde que ha habido más de un tipo de sistema y la necesidad de intercambiar datos. El artículo de Wikipedia sobre Newline tiene una descripción decente del contexto histórico. Y sugiere una variedad de soluciones a este problema específicamente para usar en el lado de Unix o en el lado de Windows.
En el lado de Unix (Linux), busque una utilidad llamada unix2dos
y su pariente cercano dos2unix
. Estos están comúnmente disponibles, ya sea como un componente de Unix comercial o como herramientas de código abierto. Si están disponibles, son la mejor respuesta porque (por lo general, consulte las páginas de manual de su Verson para obtener más detalles) son cuidadosos con los archivos que se escriben accidentalmente con ambos finales de línea. En ese desafortunado caso, un viaje a través de ambas utilidades normalmente limpiará el archivo para que sea coherente internamente. En ausencia de estos comandos convenientes, se pueden hacer muchas utilidades nativas para realizar la conversión. Por ejemplo, la conversión de terminaciones de línea CRLF de DOS a nuevas líneas de Unix se puede hacer con el tr
mando:
$ tr -d 'r' < inputfile > outputfile
Pero tenga en cuenta la advertencia de que este comando asumió que todas las líneas fueron terminadas por CRLF (o LFCR) y funciona simplemente eliminando cada carácter CR de la entrada. Se perderá cualquier personaje CR desnudo.
En el lado de DOS y Windows, solía ser mucho más sombrío. Puertos de unix2dos
y dos2unix
ciertamente existen, por ejemplo, están incluidos en el mucho herramientas Cygwin más grandes que proporcionan una emulación Unix completa en una máquina con Windows. Pero era difícil encontrar una solución que utilizara solo funciones integradas.
Windows moderno (probablemente desde Windows XP), sin embargo, es mejor. Allí, el comando FIND incorporado es mucho menos delicado sobre la elección del terminador de línea de lo que solía ser, y se puede usar para hacer la conversión requerida de terminaciones de línea Unix a terminaciones DOS. La página Wiki citada anteriormente da esta receta:
C:...> TYPE filename.u | FIND "" /V >filename.txt
La experimentación muestra que esto también funciona, pero es posible que no dé resultados idénticos por razones desconocidas:
C:...> FIND "" /V <filename.u >filename.txt
En ambos casos, crea una copia del archivo con los finales de línea modificados. Probablemente no se recomienda cambiar los archivos en su lugar.
Mencionaré otro enfoque que siempre parece tentador en el papel. Cuando usa Samba para proporcionar el recurso compartido del sistema de archivos en el servidor Linux para que Windows lo monte, hay una opción de configuración que puede establecer para el recurso compartido que lo monta en “modo texto”. Los recursos compartidos montados en “modo texto” tienen automáticamente convertidos los finales de línea. Si funciona para usted, probablemente sea la solución más limpia posible. Ambos sistemas utilizan su formato de archivo de texto preferido y ninguno tiene que preocuparse por ello. Pero pruebe con cuidado, esta solución está llena de casos extremos y escollos. Lo más importante es que no espere que los archivos binarios en un punto de montaje del sistema de archivos en modo texto se lean correctamente. A menudo lo harán, pero no necesariamente siempre.
type inputfile | find /v "" > outputfile
Deberias hacer eso. type
lee el archivo de entrada y canaliza la salida a find
con parámetros para hacer coincidir todas las líneas y enviarlas al archivo de salida. En el proceso, LF se convierte a CRLF
Una forma posible, aunque bastante engorrosa, es utilizar CertUtil.exe
, un ejecutable que se incluye de forma nativa desde Windows XP pasado, si mal no recuerdo. Aquí hay un guión posible (llamémoslo conv-eol.bat
; ver todas las explicativas rem
comentarios en el código):
@echo off
setlocal EnableExtensions DisableDelayedExpansion
rem // Define constants here:
set "_IFILE=%~1" & rem // (input file; first command line argument)
set "_OFILE=%~2" & rem // (output file; second command line argument)
set "_IEOL=0d" & rem // (incoming line-breaks; `0d` or `0a`)
set "_OEOL=0d 0a" & rem // (outgoing line-breaks; `0d`, `0a`, `0d 0a`, ``)
set "_TFILE1=%TEMP%%~n0_%RANDOM%.hex" & rem // (first temporary file)
set "_TFILE2=%TEMP%%~n0_%RANDOM%.tmp" & rem // (second temporary file)
rem // Verify input file:
< "%_IFILE%" rem/ || exit /B
rem // Convert input file to hexadecimal values (first temporary file):
CertUtil -f -encodehex "%_IFILE%" "%_TFILE1%" 4 > nul
rem // Write to second temporary file:
> "%_TFILE2%" (
setlocal EnableDelayedExpansion
rem // Read first temporary file line by line:
for /F "usebackq delims=" %%L in ("!_TFILE1!") do (
rem /* Store current line (hex. values), then replace line-breaks
rem using the given line-break codes and return result: */
set "LINE=%%L" & echo(!LINE:%_IEOL%=%_OEOL%!
)
endlocal
)
rem // Verify output file:
> "%_OFILE%" rem/ || exit /B
rem // Convert second temporary file back to text into output file:
CertUtil -f -decodehex "%_TFILE2%" "%_OFILE%" 4 > nul
rem // Clean up temporary files:
del "%_TFILE1%" "%_TFILE2%"
endlocal
exit /B
Proporcione el archivo de entrada como el primer argumento de la línea de comando y el archivo de salida como el segundo para el script (incluso pueden ser iguales):
conv-eol.bat "input-file.txt" "output-file.txt"
Los saltos de línea de entrada y salida deben especificarse como códigos de caracteres hexadecimales, mientras que 0d
representa el retorno de carro (CR) y 0a
el carácter de avance de línea (LF).
La siguiente tabla indica cómo configurar las variables _IEOL
y _OEOL
en la parte superior del script para diferentes tareas de conversión de estilo de salto de línea:
from to||Mac (CR) ||Unix/Linux (LF) ||DOS/Windows (CR+LF) Mac (CR) ||#####################||_IEOL=0d, _OEOL=0a ||_IEOL=0d, _OEOL=0d 0a Unix/Linux (LF) ||_IEOL=0a, _OEOL=0d ||#####################||_IEOL=0a, _OEOL=0d 0a DOS/Windows (CR+LF) ||_IEOL=0a, _OEOL= ||_IEOL=0d, _OEOL= ||#####################