crlf - ubuntu convert windows text file to linux
¿Cómo convertir DOS/Windows newline(CRLF) a Unix newline(LF) en un script Bash? (22)
¿Cómo puedo programar (es decir, no usar vi
) convertir las líneas nuevas de DOS / Windows a Unix?
Los comandos dos2unix
y unix2dos
no están disponibles en ciertos sistemas. ¿Cómo puedo emular estos con comandos como sed
/ awk
/ tr
?
Como una extensión de la solución Unix a DOS de Jonathan Leffler, para convertir de forma segura a DOS cuando no esté seguro de los finales de línea actuales del archivo:
sed ''/^M$/! s/$/^M/''
Esto verifica que la línea no termine en CRLF antes de convertirse a CRLF.
Curiosamente en mi git-bash en windows sed ""
hice el truco:
$ echo -e "abc/r" >tst.txt
$ file tst.txt
tst.txt: ASCII text, with CRLF line terminators
$ sed -i "" tst.txt
$ file tst.txt
tst.txt: ASCII text
Mi conjetura es que sed los ignora cuando lee líneas de entrada y siempre escribe los finales de línea de Unix en la salida.
En Linux es fácil convertir ^ M (ctrl-M) a * nix newlines (^ J) con sed.
Será algo como esto en el CLI, en realidad habrá un salto de línea en el texto. Sin embargo, el / pasa ese ^ J junto a sed:
sed ''s/^M//
/g'' < ffmpeg.log > new.log
Obtiene esto utilizando ^ V (ctrl-V), ^ M (ctrl-M) y / (barra invertida) mientras escribe:
sed ''s/^V^M//^V^J/g'' < ffmpeg.log > new.log
Este problema se puede resolver con herramientas estándar, pero hay suficientes trampas para los incautos que te recomiendo que instales el comando flip
, que fue escrito hace más de 20 años por Rahul Dhesi, el autor del zoo
. Hace un excelente trabajo al convertir formatos de archivo, mientras que, por ejemplo, evita la destrucción involuntaria de archivos binarios, lo cual es demasiado fácil si solo corriges alterando cada CRLF que ves ...
Esto funciono para mi
tr "/r" "/n" < sampledata.csv > sampledata2.csv
Hacer esto con POSIX es complicado:
POSIX Sed no soporta
/r
o/15
. Incluso si lo hizo, la opción en lugar-i
no es POSIXPOSIX Awk admite
/r
/15
, sin embargo, la opción-i inplace
no es POSIXd2u y dos2unix no son utilidades POSIX , pero ex es
POSIX ex no admite
/r
,/15
,/n
o/12
Para eliminar retornos de carro:
ex -bsc ''%!awk "{sub(//r/,/"/")}1"'' -cx file
Para agregar retornos de carro:
ex -bsc ''%!awk "{sub(/$/,/"/r/")}1"'' -cx file
Hay muchas respuestas de awk / sed / etc, así como un suplemento (ya que este es uno de los mejores resultados de búsqueda para este problema):
Puede que no tengas dos2unix pero tienes iconv ?
iconv -f UTF-16LE -t UTF-8 [filename.txt]
-f from format type
-t to format type
O todos los archivos en un directorio:
find . -name "*.sql" -exec iconv -f UTF-16LE -t UTF-8 {} -o ./{} /;
Esto ejecuta el mismo comando, en todos los archivos .sql en la carpeta actual. -o es el directorio de salida para que pueda reemplazar los archivos actuales o, por razones de seguridad / copia de seguridad, enviar a un directorio separado.
Las soluciones publicadas hasta ahora solo tratan parte del problema, convirtiendo el CRLF de DOS / Windows en el LF de Unix; la parte que faltan es que DOS usa CRLF como separador de línea, mientras que Unix usa LF como terminador de línea. La diferencia es que un archivo DOS (normalmente) no tendrá nada después de la última línea del archivo, mientras que Unix sí lo hará. Para realizar la conversión correctamente, debe agregar esa LF final (a menos que el archivo tenga una longitud cero, es decir, no tenga ninguna línea). Mi conjuro favorito para esto (con un poco de lógica adicional para manejar archivos separados por CR al estilo de Mac y no molestar a los archivos que ya están en formato Unix) es un poco de perl:
perl -pe ''if ( s//r/n?//n/g ) { $f=1 }; if ( $f || ! $m ) { s/([^/n])/z/$1/n/ }; $m=1'' PCfile.txt
Tenga en cuenta que esto envía la versión Unixified del archivo a la salida estándar. Si desea reemplazar el archivo con una versión Unixified, agregue la marca -l de perl.
Para Mac OSX si tiene Homebrew instalado [ http://brew.sh/◆◆1]
brew install dos2unix
for csv in *.csv; do dos2unix -c mac ${csv}; done;
Asegúrese de haber hecho copias de los archivos, ya que este comando modificará los archivos en su lugar. La opción -c mac hace que el switch sea compatible con osx.
Para convertir un archivo en su lugar, haga
dos2unix <filename>
Para enviar texto convertido a un archivo diferente, haga
dos2unix -n <input-file> <output-file>
Ya está instalado en Ubuntu y está disponible en homebrew con brew install dos2unix
Sé que la pregunta plantea explícitamente alternativas a esta utilidad, pero este es el primer resultado de búsqueda de Google para "convertir dos a finales de línea de Unix".
Probé sed''s / ^ M $ // ''file.txt en OSX, así como varios otros métodos ( http://www.thingy-ma-jig.co.uk/blog/25-11-2010/fixing-dos-line-endings o http://hintsforums.macworld.com/archive/index.php/t-125.html ). Ninguno funcionó, el archivo se mantuvo sin cambios (por cierto, Ctrl-v Enter era necesario para reproducir ^ M). Al final utilicé TextWrangler. No es estrictamente la línea de comando, pero funciona y no se queja.
Puedes usar tr
para convertir de DOS a Unix; sin embargo, solo puede hacer esto de manera segura si CR aparece en su archivo solo como el primer byte de un par de bytes CRLF. Este suele ser el caso. Entonces usas:
tr -d ''/015'' <DOS-file >UNIX-file
Tenga en cuenta que el nombre DOS-file
es diferente del nombre UNIX-file
; Si intenta usar el mismo nombre dos veces, terminará sin datos en el archivo.
No se puede hacer al revés (con el estándar ''tr'').
Si sabe cómo ingresar un retorno de carro en un script ( control-V , control-M para ingresar control-M), entonces:
sed ''s/^M$//'' # DOS to Unix
sed ''s/$/^M/'' # Unix to DOS
donde ''^ M'' es el carácter control-M. También puede usar el mecanismo de bash
ANSI-C de bash
para especificar el retorno de carro:
sed $''s//r$//'' # DOS to Unix
sed $''s/$//r/'' # Unix to DOS
Sin embargo, si va a tener que hacer esto muy a menudo (más de una vez, aproximadamente hablando), es mucho más sensato instalar los programas de conversión (por ejemplo, dos2unix
y unix2dos
, o quizás dtou
y utod
) y usarlos.
Puedes usar awk. Establezca el separador de registros ( RS
) en una expresión regular que coincida con todos los posibles caracteres de nueva línea o caracteres. Y establezca el separador de registro de salida ( ORS
) en el carácter de nueva línea de estilo Unix.
awk ''BEGIN{RS="/r|/n|/r/n|/n/r";ORS="/n"}{print}'' windows_or_macos.txt > unix.txt
Puedes usar vim programáticamente con la opción -c {comando}:
Dos a Unix:
vim file.txt -c "set ff=unix" -c ":wq"
Unix a dos:
vim file.txt -c "set ff=dos" -c ":wq"
Súper duper fácil con PCRE;
Como un script, o reemplace $@
con sus archivos.
#!/usr/bin/env bash
perl -pi -e ''s//r/n//n/g'' -- $@
Esto sobrescribirá tus archivos en su lugar!
Recomiendo solo hacer esto con una copia de seguridad (control de versión o de otro tipo)
Si no tiene acceso a dos2unix , pero puede leer esta página, puede copiar / pegar dos2unix.py desde aquí.
#!/usr/bin/env python
"""/
convert dos linefeeds (crlf) to unix (lf)
usage: dos2unix.py <input> <output>
"""
import sys
if len(sys.argv[1:]) != 2:
sys.exit(__doc__)
content = ''''
outsize = 0
with open(sys.argv[1], ''rb'') as infile:
content = infile.read()
with open(sys.argv[2], ''wb'') as output:
for line in content.splitlines():
outsize += len(line) + 1
output.write(line + ''/n'')
print("Done. Saved %s bytes." % (len(content)-outsize))
Cruzada desde superuser .
Solo tuve que reflexionar sobre la misma pregunta (en el lado de Windows, pero igualmente aplicable a Linux). Sorprendentemente, nadie mencionó una forma muy automatizada de hacer la conversión de CRLF <-> LF para archivos de texto usando una opción de zip -ll
buena vieja (Info- CREMALLERA):
zip -ll textfiles-lf.zip files-with-crlf-eol.*
unzip textfiles-lf.zip
NOTA: esto crearía un archivo zip que conserva los nombres del archivo original pero que convierte los finales de línea a LF. Luego, unzip
extraería los archivos como zip''ed, es decir, con sus nombres originales (pero con terminaciones LF), lo que le pedirá que sobrescriba los archivos originales locales, si los hubiera.
Extracto relevante de la zip --help
:
zip --help
...
-l convert LF to CR LF (-ll CR LF to LF)
TIMTOWTDI!
perl -pe ''s//r/n//n/; s/([^/n])/z/$1/n/ if eof'' PCfile.txt
Basado en @GordonDavisson
Hay que considerar la posibilidad de [noeol]
...
Una solución awk aún más simple con un programa:
awk -v ORS=''/r/n'' ''1'' unix.txt > dos.txt
Técnicamente ''1'' es su programa, b / c awk requiere uno cuando se le da una opción.
ACTUALIZACIÓN : Después de volver a visitar esta página por primera vez en mucho tiempo, me di cuenta de que nadie ha publicado una solución interna, así que aquí hay una:
while IFS= read -r line;
do printf ''%s/n'' "${line%$''/r''}";
done < dos.txt > unix.txt
Usando AWK puedes hacer:
awk ''{ sub("/r$", ""); print }'' dos.txt > unix.txt
Usando Perl puedes hacer:
perl -pe ''s//r$//'' < dos.txt > unix.txt
sed --expression=''s//r/n//n/g''
Como la pregunta menciona sed, esta es la forma más directa de usar sed para lograrlo. Lo que dice la expresión es reemplazar todo el retorno de carro y el salto de línea solo con el salto de línea. Eso es lo que necesitas cuando vas de Windows a Unix. He verificado que funciona.
tr -d "/r" < file
Echa un vistazo here para ver ejemplos usando sed
:
# IN UNIX ENVIRONMENT: convert DOS newlines (CR/LF) to Unix format.
sed ''s/.$//'' # assumes that all lines end with CR/LF
sed ''s/^M$//'' # in bash/tcsh, press Ctrl-V then Ctrl-M
sed ''s//x0D$//'' # works on ssed, gsed 3.02.80 or higher
# IN UNIX ENVIRONMENT: convert Unix newlines (LF) to DOS format.
sed "s/$/`echo -e ///r`/" # command line under ksh
sed ''s/$''"/`echo ///r`/" # command line under bash
sed "s/$/`echo ///r`/" # command line under zsh
sed ''s/$//r/'' # gsed 3.02.80 or higher
Use sed -i
para la conversión en el lugar, por ejemplo sed -i ''s/..../'' file
.