¿Cómo convertir en masa todos los archivos en una rama del sistema de archivos entre el formato de salto de línea de Unix y Windows?

14

Todo el mundo sabe :-) que en Windows las líneas de archivos de texto sin formato terminan con CR + LF, y en Unix y Linux, solo con LF. ¿Cómo puedo convertir rápidamente todos mis archivos de código fuente de un formato a otro y viceversa?

Ivan
fuente

Respuestas:

17

Eso depende: si los archivos están bajo el control de la versión, esta podría ser una decisión poco popular que contamina el historial. Git tiene la opción de convertir automáticamente los finales de línea al finalizar la compra.

Si no le importa y desea convertir rápidamente, hay programas como fromdos/ todosy dos2unix/ unix2dosque hacen esto por usted. Se puede utilizar find: find . -type f -name '*.php' -exec dos2unix '{}' +.

janmoesen
fuente
7

Hay varios programas dedicados, que incluyen

  • dos2unixy unix2dosde las herramientas dos2unix
  • todosy fromdosde las herramientas tofrodos

Simplemente elija la herramienta para la dirección adecuada y pase los nombres de los archivos a convertir en la línea de comando.


Si no tiene ninguno, pero tiene Linux o Cygwin:

sed -i -e 's/\r\+$//' filename             # dos|unix -> unix
sed -i -e 's/\r*$/\r/' filename            # dos|unix -> dos

Si tienes perl:

perl -i -pe 's/\r+$//' filename            # dos|unix -> unix
perl -i -pe 's/\r*$/\r/' filename          # dos|unix -> dos

Con solo las herramientas POSIX (incluido BusyBox), para pasar de unix a dos, deberá pasar el carácter CR literalmente en el comando sed.

cr=$(echo | tr '\n' '\r')
sed -e "s/$cr*\$/$cr/" <filename >filename.dos
mv filename.dos filename

En la otra dirección, simplemente puede eliminar todos los CR:

tr -d '\r' <filename >filename.dos
mv filename.dos filename

Puede usar comodines para convertir muchos archivos en el mismo directorio a la vez, p. Ej.

sed -i -e 's/\r\+$//' *.txt

Para convertir todos los archivos en el directorio actual y sus subdirectorios, si su shell es zsh, puede usar **/, por ejemplo

sed -i -e 's/\r\+$//' **/*.txt

Puede usar **/en bash ≥4, pero debe ejecutar shopt -s globstarprimero (puede poner esta línea en su ~/.bashrc). Puedes usarlo **/en ksh93, pero set -o globstarprimero debes ejecutarlo (puedes poner esta línea en tu ~/.kshrc.

Si solo puede usar las herramientas que requieren una redirección, use un forbucle.

for x in *.txt; do
  tr -d '\r' <"$x" >"$x.dos"
  mv -- "$x.dos" "$x"
done

Si no tiene **/o necesita una coincidencia más compleja para seleccionar qué archivos convertir, use el findcomando. Aquí hay un ejemplo de Linux / Cygwin que convierte todos los archivos bajo el directorio actual y sus subdirectorios de forma recursiva, excepto los archivos llamados .oy bajo los subdirectorios llamados bin.

find -name 'bin' -type d -prune -o \
     \! -name '*.o' \
     -exec sed -i -e 's/\r\+$//' {} +

Aquí hay un ejemplo de POSIX. Le decimos findque inicie un shell que pueda realizar la redirección necesaria.

find -name 'bin' -type d -prune -o \
     \! -name '*.o' \
     -exec sh -c '
       tr -d '\r' <"$0" >"$0.dos"
       mv -- "$0.dos" "$0"
' {} \;

Puede hacer que el findmétodo sea un poco más rápido, a expensas de un código más complejo, utilizando un bucle en el comando de shell.

find -name 'bin' -type d -prune -o \
     \! -name '*.o' \
     -exec sh -c '
       for x; do
         tr -d '\r' <"$x" >"$x.dos"
         mv -- "$x.dos" "$x"
       done
' _ {} +
Gilles 'SO- deja de ser malvado'
fuente
2

winscp también se convertirá automáticamente, si se le indica .

Si sus archivos residen todos en el mismo directorio:

DIRECTORY=/your/directory
unix2dos $DIRECTORY/*
Nils
fuente
¿Puede describir un poco más cómo lograrlo a través de WinSCP?
harish sharma
@harishsharma Agregué un enlace obove a "dicho".
Nils