En general, solo instale dos2unixusando su administrador de paquetes, realmente es mucho más simple y existe en la mayoría de las plataformas.
Brad Koch
1
¡Convenido! @BradKoch Simple como 'brew install dos2unix' en Mac OSX
SmileIT
Respuestas:
323
Puede usar trpara convertir de DOS a Unix; sin embargo, solo puede hacerlo 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. Luego usas:
tr -d '\015'<DOS-file >UNIX-file
Tenga en cuenta que el nombre DOS-filees diferente del nombre UNIX-file; Si intenta usar el mismo nombre dos veces, terminará sin datos en el archivo.
No puede hacerlo al revés (con el estándar 'tr').
Si sabe cómo ingresar el retorno de carro en un script ( control-V, control-Mpara 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 bashcotización ANSI-C 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 con mucha frecuencia (más de una vez, en términos generales), es mucho más sensato instalar los programas de conversión (por ejemplo , dos2unixy unix2dos, o quizás dtouy utod) y usarlos.
Si necesita procesar directorios y subdirectorios completos, puede usar zip:
zip -r -ll zipfile.zip somedir/
unzip zipfile.zip
Esto creará un archivo zip con finales de línea cambiados de CRLF a CR. unzipluego volverá a colocar los archivos convertidos en su lugar (y le preguntará archivo por archivo; puede responder: Sí a todo). Créditos a @vmsnomad por señalar esto.
usando tr -d '\015' <DOS-file >UNIX-filewhere DOS-file== UNIX-filesolo da como resultado un archivo vacío. El archivo de salida tiene que ser un archivo diferente, desafortunadamente.
Buttle Butkus
3
@ButtleButkus: Bueno, sí; Por eso usé dos nombres diferentes. Si elimina el archivo de entrada antes de que el programa lo lea todo, como lo hace cuando usa el mismo nombre dos veces, termina con un archivo vacío. Ese es un comportamiento uniforme en sistemas tipo Unix. Requiere un código especial para manejar la sobrescritura de un archivo de entrada de forma segura. Siga las instrucciones y estará bien.
Jonathan Leffler
Parece que recuerdo alguna vez la funcionalidad de reemplazo de búsqueda en el archivo.
Buttle Butkus
44
Hay lugares; tienes que saber dónde encontrarlos. Dentro de los límites, la sedopción GNU -i(para el lugar) funciona; Los límites son archivos vinculados y enlaces simbólicos. El sortcomando 'siempre' (desde 1979, si no antes) admitió la -oopción que puede enumerar uno de los archivos de entrada. Sin embargo, eso es en parte porque sortdebe leer toda su entrada antes de que pueda escribir cualquiera de sus resultados. Otros programas admiten esporádicamente sobrescribir uno de sus archivos de entrada. Puede encontrar un programa de propósito general (script) para evitar problemas en 'El entorno de programación UNIX' de Kernighan & Pike.
Jonathan Leffler
3
La tercera opción funcionó para mí, gracias. Utilicé la opción -i: sed -i $'s/\r$//' filename- para editar en su lugar. Estoy trabajando en una máquina que no tiene acceso a Internet, por lo que la instalación del software es un problema.
# 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
Uso sed -ipara la conversión en el lugar, por ejemplo sed -i 's/..../' file.
Usé una variante ya que mi archivo solo tenía \r:tr "\r" "\n" < infile > outfile
Matt Todd
1
@MattTodd, ¿podría publicar esto como respuesta? el -dse ofrece con más frecuencia y no ayudará en la "única \r" situación.
n611x007
55
Tenga en cuenta que la propuesta \rde \nmapeo tiene el efecto de doble espacio entre los archivos; cada línea CRLF que termina en DOS se convierte \n\nen Unix.
Jonathan Leffler
¿Puedo hacer esto de forma recursiva?
Aaron Franke el
36
Hacer esto con POSIX es complicado:
POSIX Sed no es compatible con \ro \15. Incluso si lo hiciera, la opción en el lugar -ino es POSIX
POSIX Awk es compatible \ry \15, sin embargo, la -i inplaceopción no es POSIX
Parece que POSIX es trcompatible \r. Por lo tanto, también puede usar printf '%s\n' '%!tr -d "\r"' x | ex file(aunque está garantizado, esto se elimina \rincluso si no precede inmediatamente \n). Además, POSIX no especifica la -bopción a ex.
Comodín
1
Hacer esto en POSIX es fácil. Incruste el literal CR en el script escribiéndolo (es control-M).
Joshua
28
Puede usar vim mediante programación 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"
"set ff = unix / dos" significa cambiar el formato de archivo (ff) del archivo al formato de final de línea Unix / DOS
": wq" significa escribir el archivo en el disco y salir del editor (permitiendo usar el comando en un bucle)
Esta parecía la solución más elegante, pero la falta de explicación sobre lo que significa wq es lamentable.
Jorrick Sleijster
55
Cualquiera que use visabrá lo que :wqsignifica. Para aquellos que no lo hacen, los 3 caracteres significan 1) abrir el área de comando vi, 2) escribir y 3) salir.
David Newcomb
No tenía idea de que podía agregar comandos interactivamente a vim desde la CLI
Sé que la pregunta pide alternativas a dos2unix, pero es el primer resultado de Google.
Boris
18
Este problema se puede resolver con herramientas estándar, pero hay suficientes trampas para los incautos que recomiendo que instale el flipcomando, que fue escrito hace más de 20 años por Rahul Dhesi, el autor de zoo. Hace un excelente trabajo al convertir formatos de archivo y, por ejemplo, evita la destrucción accidental de archivos binarios, lo cual es un poco demasiado fácil si simplemente corres alterando cada CRLF que ves ...
Tuve la experiencia de romper la mitad de mi sistema operativo simplemente ejecutando texxto con una bandera incorrecta. Tenga cuidado, especialmente si desea hacerlo en carpetas enteras.
A_P
14
Las soluciones publicadas hasta ahora solo abordan parte del problema, convirtiendo el CRLF de DOS / Windows en LF de Unix; la parte que les falta 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 (generalmente) no tendrá nada después de la última línea del archivo, mientras que Unix sí. Para realizar la conversión correctamente, debe agregar ese LF final (a menos que el archivo tenga una longitud cero, es decir, no tenga líneas). Mi encantamiento favorito para esto (con una pequeña lógica agregada para manejar archivos separados por CR de estilo Mac, y no molestar a los archivos que ya están en formato unix) es un poco perl:
Tenga en cuenta que esto envía la versión Unixified del archivo a stdout. Si desea reemplazar el archivo con una versión Unixified, agregue la -ibandera de perl .
@LudovicZenohateLagouardette ¿Era un archivo de texto sin formato (es decir, csv o texto con tabulación), o algo más? Si estaba en algún formato de base de datos, manipularlo como si fuera texto es muy probable que corrompa su estructura interna.
Gordon Davisson el
Un texto sin formato csv, pero creo que la búsqueda fue extraña. Creo que se equivocó por eso. Sin embargo no te preocupes. Siempre estoy recopilando copias de seguridad y este ni siquiera era el conjunto de datos real, solo uno de 1 gb. El real es un 26gb.
Ludovic Zenohate Lagouardette
14
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))
El uso es engañoso. El real dos2unixconvierte todos los archivos de entrada por defecto. Su uso implica -nparámetro. Y lo real dos2unixes un filtro que lee desde stdin, escribe en stdout si no se proporcionan los archivos.
jfs
8
Super duper fácil con PCRE;
Como secuencia de comandos, o reemplazar $@con sus archivos.
¡Gracias! Esto funciona, aunque estoy escribiendo el nombre del archivo y no --. Elegí esta solución porque es fácil de entender y adaptar para mí. Para su información, esto es lo que hacen los interruptores: -pasumir un bucle "mientras que la entrada", -ieditar el archivo de entrada en su lugar, -eejecutar el siguiente comando
Rolf
Estrictamente hablando, PCRE es una reimplementación del motor de expresiones regulares de Perl, no el motor de expresiones regulares de Perl. Ambos tienen esta capacidad, aunque también hay diferencias, a pesar de la implicación en el nombre.
tripleee
6
Una solución awk aún más simple sin 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 la 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 había publicado aún 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
Eso es útil, pero para ser claros: esto traduce Unix -> Windows / DOS, que es la dirección opuesta a lo que solicitó el OP.
mklement0
55
Fue hecho a propósito, dejado como ejercicio para el autor. eyerollsawk -v RS='\r\n' '1' dos.txt > unix.txt
nawK
Genial (y felicitaciones por la delicadeza pedagógica).
mklement0
1
"b / c awk requiere uno cuando se le da la opción". - awk siempre requiere un programa, ya sea que las opciones estén especificadas o no.
mklement0
1
La solución bash pura es interesante, pero mucho más lenta que una solución awko equivalente sed. Además, debe usar while IFS= read -r linepara preservar fielmente las líneas de entrada, de lo contrario se recortará el espacio en blanco inicial y final (alternativamente, no use ningún nombre de variable en el readcomando y trabaje con $REPLY).
mklement0
5
Solo tenía 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 CRLF <-> LF para archivos de texto usando la buena zip -llopción anterior (Info-ZIP):
zip -ll textfiles-lf.zip files-with-crlf-eol.*
unzip textfiles-lf.zip
NOTA: esto crearía un archivo zip conservando los nombres de archivo originales pero convirtiendo las terminaciones de línea a LF. Luego unzipextraería los archivos como zip'ed, es decir, con sus nombres originales (pero con terminaciones LF), lo que provocaría sobrescribir los archivos originales locales, si los hubiera.
Extracto relevante de zip --help:
zip --help
...-l convert LF to CR LF (-ll CR LF to LF)
brew install dos2unix
for csv in*.csv;do dos2unix -c mac ${csv};done;
Asegúrese de haber realizado copias de los archivos, ya que este comando modificará los archivos en su lugar. La opción -c mac hace que el conmutador sea compatible con osx.
Esta respuesta realmente no es la pregunta del póster original.
hlin117
2
Los usuarios de OS X no deben usar -c mac, que es para convertir solo CRnuevas líneas anteriores a OS X. Desea usar ese modo solo para archivos hacia y desde Mac OS 9 o anterior.
askewchan
2
TIMTOWTDI!
perl -pe 's/\r\n/\n/; s/([^\n])\z/$1\n/ if eof'PCfile.txt
Puedes usar awk. Establezca el separador de registros ( RS) en una expresión regular que coincida con todos los caracteres o caracteres de nueva línea posibles. Y establezca el separador de registro de salida ( ORS) en el carácter de nueva línea de estilo Unix.
Como la pregunta menciona sed, esta es la forma más directa de usar sed para lograr esto. Lo que dice la expresión es reemplazar todo retorno de carro y avance de línea solo con avance de línea. Eso es lo que necesitas cuando pasas de Windows a Unix. Verifiqué que funciona.
Hola, John Paul: esta respuesta se marcó para su eliminación, así que apareció en una cola de revisión para mí. En general, cuando tiene una pregunta como esta que tiene 8 años, con 22 respuestas, querrá explicar cómo su respuesta es útil de una manera que otras respuestas existentes no lo son.
zzxyz
0
Como una extensión de la solución Unix a DOS de Jonathan Leffler, para convertir de manera segura a DOS cuando no esté seguro de las terminaciones de línea actuales del archivo:
sed '/^M$/! s/$/^M/'
Esto verifica que la línea no termine en CRLF antes de convertir a CRLF.
Hice un script basado en la respuesta aceptada para que pueda convertirlo directamente sin necesidad de un archivo adicional al final y eliminar y cambiar el nombre después.
solo asegúrese de que si tiene un archivo como "file1.txt" que "file1.txt2" ya no existe o se sobrescribirá, lo uso como un lugar temporal para almacenar el archivo.
dos2unix
usando su administrador de paquetes, realmente es mucho más simple y existe en la mayoría de las plataformas.Respuestas:
Puede usar
tr
para convertir de DOS a Unix; sin embargo, solo puede hacerlo 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. Luego usas:Tenga en cuenta que el nombre
DOS-file
es diferente del nombreUNIX-file
; Si intenta usar el mismo nombre dos veces, terminará sin datos en el archivo.No puede hacerlo al revés (con el estándar 'tr').
Si sabe cómo ingresar el retorno de carro en un script ( control-V, control-Mpara ingresar control-M), entonces:
donde '^ M' es el carácter control-M. También puede usar el mecanismo de
bash
cotización ANSI-C para especificar el retorno de carro:Sin embargo, si va a tener que hacer esto con mucha frecuencia (más de una vez, en términos generales), es mucho más sensato instalar los programas de conversión (por ejemplo ,
dos2unix
yunix2dos
, o quizásdtou
yutod
) y usarlos.Si necesita procesar directorios y subdirectorios completos, puede usar
zip
:Esto creará un archivo zip con finales de línea cambiados de CRLF a CR.
unzip
luego volverá a colocar los archivos convertidos en su lugar (y le preguntará archivo por archivo; puede responder: Sí a todo). Créditos a @vmsnomad por señalar esto.fuente
tr -d '\015' <DOS-file >UNIX-file
whereDOS-file
==UNIX-file
solo da como resultado un archivo vacío. El archivo de salida tiene que ser un archivo diferente, desafortunadamente.sed
opción GNU-i
(para el lugar) funciona; Los límites son archivos vinculados y enlaces simbólicos. Elsort
comando 'siempre' (desde 1979, si no antes) admitió la-o
opción que puede enumerar uno de los archivos de entrada. Sin embargo, eso es en parte porquesort
debe leer toda su entrada antes de que pueda escribir cualquiera de sus resultados. Otros programas admiten esporádicamente sobrescribir uno de sus archivos de entrada. Puede encontrar un programa de propósito general (script) para evitar problemas en 'El entorno de programación UNIX' de Kernighan & Pike.sed -i $'s/\r$//' filename
- para editar en su lugar. Estoy trabajando en una máquina que no tiene acceso a Internet, por lo que la instalación del software es un problema.mira aquí para ejemplos usando
sed
:Uso
sed -i
para la conversión en el lugar, por ejemplosed -i 's/..../' file
.fuente
\r
:tr "\r" "\n" < infile > outfile
-d
se ofrece con más frecuencia y no ayudará en la "única\r
" situación.\r
de\n
mapeo tiene el efecto de doble espacio entre los archivos; cada línea CRLF que termina en DOS se convierte\n\n
en Unix.Hacer esto con POSIX es complicado:
POSIX Sed no es compatible con
\r
o\15
. Incluso si lo hiciera, la opción en el lugar-i
no es POSIXPOSIX Awk es compatible
\r
y\15
, sin embargo, la-i inplace
opción no es POSIXd2u y dos2unix no son utilidades POSIX , pero ex es
POSIX ex no soporta
\r
,\15
,\n
o\12
Para eliminar retornos de carro:
Para agregar retornos de carro:
fuente
tr
compatible\r
. Por lo tanto, también puede usarprintf '%s\n' '%!tr -d "\r"' x | ex file
(aunque está garantizado, esto se elimina\r
incluso si no precede inmediatamente\n
). Además, POSIX no especifica la-b
opción aex
.Puede usar vim mediante programación con la opción -c {comando}:
Dos a Unix:
Unix a dos:
"set ff = unix / dos" significa cambiar el formato de archivo (ff) del archivo al formato de final de línea Unix / DOS
": wq" significa escribir el archivo en el disco y salir del editor (permitiendo usar el comando en un bucle)
fuente
vi
sabrá lo que:wq
significa. Para aquellos que no lo hacen, los 3 caracteres significan 1) abrir el área de comando vi, 2) escribir y 3) salir.Usando AWK puedes hacer:
Usando Perl puedes hacer:
fuente
awk
.Para convertir un archivo en su lugar, use
Para enviar el texto convertido a un archivo diferente, use
Puede instalarlo en Ubuntu o Debian con
o en macOS usando homebrew
fuente
Este problema se puede resolver con herramientas estándar, pero hay suficientes trampas para los incautos que recomiendo que instale el
flip
comando, que fue escrito hace más de 20 años por Rahul Dhesi, el autor dezoo
. Hace un excelente trabajo al convertir formatos de archivo y, por ejemplo, evita la destrucción accidental de archivos binarios, lo cual es un poco demasiado fácil si simplemente corres alterando cada CRLF que ves ...fuente
Las soluciones publicadas hasta ahora solo abordan parte del problema, convirtiendo el CRLF de DOS / Windows en LF de Unix; la parte que les falta 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 (generalmente) no tendrá nada después de la última línea del archivo, mientras que Unix sí. Para realizar la conversión correctamente, debe agregar ese LF final (a menos que el archivo tenga una longitud cero, es decir, no tenga líneas). Mi encantamiento favorito para esto (con una pequeña lógica agregada para manejar archivos separados por CR de estilo Mac, y no molestar a los archivos que ya están en formato unix) es un poco perl:
Tenga en cuenta que esto envía la versión Unixified del archivo a stdout. Si desea reemplazar el archivo con una versión Unixified, agregue la
-i
bandera de perl .fuente
Si no tiene acceso a dos2unix , pero puede leer esta página, puede copiar / pegar dos2unix.py desde aquí.
Publicación cruzada del superusuario .
fuente
dos2unix
convierte todos los archivos de entrada por defecto. Su uso implica-n
parámetro. Y lo realdos2unix
es un filtro que lee desde stdin, escribe en stdout si no se proporcionan los archivos.Super duper fácil con PCRE;
Como secuencia de comandos, o reemplazar
$@
con sus archivos.fuente
--
. Elegí esta solución porque es fácil de entender y adaptar para mí. Para su información, esto es lo que hacen los interruptores:-p
asumir un bucle "mientras que la entrada",-i
editar el archivo de entrada en su lugar,-e
ejecutar el siguiente comandoUna solución awk aún más simple sin un programa:
Técnicamente '1' es su programa, b / c awk requiere uno cuando se le da la 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 había publicado aún una solución interna, así que aquí hay una:
fuente
awk -v RS='\r\n' '1' dos.txt > unix.txt
awk
o equivalentesed
. Además, debe usarwhile IFS= read -r line
para preservar fielmente las líneas de entrada, de lo contrario se recortará el espacio en blanco inicial y final (alternativamente, no use ningún nombre de variable en elread
comando y trabaje con$REPLY
).Solo tenía 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 CRLF <-> LF para archivos de texto usando la buena
zip -ll
opción anterior (Info-ZIP):NOTA: esto crearía un archivo zip conservando los nombres de archivo originales pero convirtiendo las terminaciones 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 provocaría sobrescribir los archivos originales locales, si los hubiera.Extracto relevante de
zip --help
:fuente
Curiosamente en mi git-bash en windows ya
sed ""
hizo el truco:Supongo que sed los ignora al leer líneas de entrada y siempre escribe terminaciones de línea unix en la salida.
fuente
Esto funciono para mi
fuente
Para Mac osx si tiene instalado homebrew [ http://brew.sh/font>[1]
Asegúrese de haber realizado copias de los archivos, ya que este comando modificará los archivos en su lugar. La opción -c mac hace que el conmutador sea compatible con osx.
fuente
-c mac
, que es para convertir soloCR
nuevas líneas anteriores a OS X. Desea usar ese modo solo para archivos hacia y desde Mac OS 9 o anterior.TIMTOWTDI!
Basado en @GordonDavisson
Hay que considerar la posibilidad de
[noeol]
...fuente
Puedes usar awk. Establezca el separador de registros (
RS
) en una expresión regular que coincida con todos los caracteres o caracteres de nueva línea posibles. Y establezca el separador de registro de salida (ORS
) en el carácter de nueva línea de estilo Unix.fuente
git diff
muestra ^ M, editado en vim)En Linux es fácil convertir ^ M (ctrl-M) a * nix newlines (^ J) con sed.
Será algo así en la CLI, en realidad habrá un salto de línea en el texto. Sin embargo, el \ pasa ese ^ J a sed:
Obtiene esto usando ^ V (ctrl-V), ^ M (ctrl-M) y \ (barra invertida) mientras escribe:
fuente
Como la pregunta menciona sed, esta es la forma más directa de usar sed para lograr esto. Lo que dice la expresión es reemplazar todo retorno de carro y avance de línea solo con avance de línea. Eso es lo que necesitas cuando pasas de Windows a Unix. Verifiqué que funciona.
fuente
Como una extensión de la solución Unix a DOS de Jonathan Leffler, para convertir de manera segura a DOS cuando no esté seguro de las terminaciones de línea actuales del archivo:
Esto verifica que la línea no termine en CRLF antes de convertir a CRLF.
fuente
Hice un script basado en la respuesta aceptada para que pueda convertirlo directamente sin necesidad de un archivo adicional al final y eliminar y cambiar el nombre después.
solo asegúrese de que si tiene un archivo como "file1.txt" que "file1.txt2" ya no existe o se sobrescribirá, lo uso como un lugar temporal para almacenar el archivo.
fuente
Con bash 4.2 y versiones más recientes, puede usar algo como esto para eliminar el CR final, que solo usa las funciones integradas de bash:
fuente
Intenté 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 permaneció sin cambios (por cierto Ctrl-v Enter fue necesario para reproducir ^ M). Al final usé TextWrangler. No es estrictamente la línea de comando, pero funciona y no se queja.
fuente