¿Cómo puedo programáticamente (es decir, no usar vi
) convertir líneas nuevas de DOS/Windows en Unix? Los comandos dos2unix
y unix2dos
no están disponibles en ciertos sistemas. ¿Cómo puedo emular estos con comandos como sed
/awk
/tr
?Cómo convertir DOS/Windows nueva línea (CRLF) a Unix nueva línea ( n) en un script Bash?
Respuesta
Utilizando AWK que puede hacer:
awk '{ sub("\r$", ""); print }' dos.txt > unix.txt
Utilizando Perl que puede hacer:
perl -pe 's/\r$//' <dos.txt> unix.txt
Una solución agradable, _portable_ 'awk'. – mklement0
Se puede utilizar para convertir tr
de DOS a Unix; sin embargo, solo puede hacerlo de forma segura si CR aparece en su archivo solo como el primer byte de un par de bytes CRLF. Este suele ser el caso. A continuación se usa:
tr -d '\015' <DOS-file >UNIX-file
Tenga en cuenta que el nombre DOS-file
es diferente del nombre UNIX-file
; si intentas usar el mismo nombre dos veces, terminarás sin datos en el archivo.
No puede hacerlo al revés (con 'tr' estándar).
Si sabe cómo introducir retorno de carro en un guión (de control-V, Control-M para entrar en Control-M), entonces:
sed 's/^M$//' # DOS to Unix
sed 's/$/^M/' # Unix to DOS
donde el '^ M' es el caracter de control-M También puede utilizar el mecanismo bash
ANSI-C Quoting para especificar el retorno de carro:
sed $'s/\r$//' # DOS to Unix
sed $'s/$/\r/' # Unix to DOS
Sin embargo, si usted va a tener que hacer esto muy a menudo (más de una vez, en términos generales), es mucho más sensato instale los programas de conversión (por ejemplo, dos2unix
y unix2dos
, o quizás dtou
y utod
) y úselos.
usando 'tr -d '\ 015'
@ButtleButkus: Bueno, sí; es por eso que utilicé dos nombres diferentes. Si borra el archivo de entrada antes de que el programa lo lea todo, como 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. Sigue las instrucciones y estarás bien. –
Me parece recordar alguna función de búsqueda-reemplazo dentro del archivo. –
tr -d "\r" < file
echar un vistazo para 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
Uso sed -i
para la conversión en el lugar, por ejemplo, sed -i 's/..../' file
.
Utilicé una variante ya que mi archivo solo tenía '\ r':' tr "\ r" "\ n" < infile > archivo de salida' –
@MattTodd ¿podría publicar esto como respuesta? el '-d' aparece con más frecuencia y no ayudará en la situación" only '\ r'". – n611x007
Tenga en cuenta que la asignación propuesta '\ r' a' \ n' tiene el efecto de doble espaciado de los archivos; cada línea CRLF que termina en DOS se convierte en '\ n \ n' en Unix. –
Las soluciones publicadas hasta ahora solo se ocupan de parte del problema, convirtiendo DOS/Windows 'CRLF en LF de Unix; la parte que faltan es que DOS usa CRLF como una línea separador, mientras que Unix usa LF como una línea terminador. La diferencia es que un archivo DOS (por lo general) no tendrá nada después de la última línea del archivo, mientras que Unix lo hará. Para realizar la conversión correctamente, debe agregar ese LF final (a menos que el archivo sea de longitud cero, es decir, no tenga líneas en absoluto).Mi favorito para este encantamiento (con un poco de lógica adicional para gestionar archivos CR-separado de estilo Mac, y no molestar a los archivos ya that're 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 stdout. Si desea reemplazar el archivo con una versión no unificada, agregue el indicador -i
de perl.
RIP mi archivo de datos. se equivocó en algún lugar xD –
@LudovicZenohateLagouardette ¿Se trataba de un archivo de texto sin formato (es decir, csv o texto con tabulación), o alguna otra cosa? Si estaba en algún formato ish de base de datos, manipularlo como si fuera texto es muy probable que dañe su estructura interna. –
Un csv de texto sin formato, pero creo que el descubrimiento fue extraño. Creo que fue un desastre debido a eso. Sin embargo, no te preocupes. Siempre estoy recopilando copias de seguridad y este ni siquiera era el conjunto de datos real, solo un archivo de 1 gb. Lo real es 26 gb. –
Este problema se puede resolver con herramientas estándar, pero hay suficientes trampas para los incautos que recomiendo instalar el comando flip
, que fue escrito hace más de 20 años por Rahul Dhesi, el autor de zoo
. Se hace un trabajo excelente conversión de formatos de archivo, mientras que, por ejemplo, evitar la destrucción inadvertida de archivos binarios, que es un poco demasiado fácil si sólo Carrera alrededor de la alteración de cada CRLF ves ...
Probé sed ' s/^ M $ // 'archivo.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 fue necesario para reproducir^M). Al final usé TextWrangler. No es estrictamente una línea de comandos, pero funciona y no se queja.
Si usted no tiene acceso a dos2unix, pero puede leer esta página, entonces se 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))
Publicación cruzada desde superuser.
El uso es engañoso. El verdadero 'dos2unix' convierte * todos * los archivos de entrada por defecto. Su uso implica el parámetro '-n'. Y el 'dos2unix' real es un filtro que lee de stdin, escribe en stdout si no se proporcionan los archivos. – jfs
@ J.F.Sebastian que 'dos2unix' herramientas es real? ¿Está en el estándar POSIX? –
¿Qué 'dos2unix' quieres decir? Quise decir: 'sudo apt-get install dos2unix' – jfs
Hacer esto con POSIX es complicado:
POSIX Sed no admite
\r
o\15
. Incluso si lo hiciera, la opción en su lugar-i
no es POSIXPOSIX Awk ¿Apoya
\r
y\15
, sin embargo la opción-i inplace
no es POSIXd2u y dos2unix no son POSIX utilities, pero ex es
POSIX ex no soporta
\r
,\15
,\n
o\12
Para quitar los retornos de carro:
ex -bsc '%!awk "{sub(/\r/,\"\")}1"' -cx file
Para añadir retornos de carro:
ex -bsc '%!awk "{sub(/$/,\"\r\")}1"' -cx file
Parece que [POSIX 'tr' admite' \ r'.] (Http://pubs.opengroup.org/onlinepubs/9699919799/utilities/tr.html#tag_20_132_13) Así que también puede usar 'printf '% s \ n ''%! tr -d "\ r" 'x | ex file' (aunque se concede, esto elimina '\ r' incluso si no está inmediatamente antes de' \ n'). Además, la opción '-b' a' ex' no está especificada por POSIX. – Wildcard
Para Mac OS X si ha instalado homebrew [http://brew.sh/][1]
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.
'dos2unix' resultó ser bastante útil. – HelloGoodbye
Esta respuesta realmente no es la pregunta del cartel original. – hlin117
Los usuarios de OS X no deben usar '-c mac', que es para convertir líneas nuevas' 'solo'' de OS-X. Desea utilizar ese modo solo para archivos hacia y desde Mac OS 9 o anteriores. – askewchan
Una solución awk aún más simple w/o un programa:
awk -v ORS='\r\n' '1' unix.txt > dos.txt
Técnicamente '1' es su programa, b/c awk requiere que uno cuando se les da la opción.
ACTUALIZACIÓN: Después de volver a visitar esta página por primera vez en mucho tiempo me di cuenta que todavía nadie ha publicado una solución interna, por lo que aquí es una:
while IFS= read -r line;
do printf '%s\n' "${line%$'\r'}";
done <dos.txt> unix.txt
Eso es útil, pero solo para ser claro: esto traduce Unix -> Windows/DOS, que es la dirección opuesta a lo que solicitó el OP. – mklement0
Fue hecho a propósito, dejado como ejercicio para el autor. _eyerolls_ 'awk -v RS = '\ r \ n' '1' dos.txt> unix.txt' – nawK
Estupendo (y felicitaciones para la finura pedagógica). – mklement0
Esto funcionó para mí
tr "\r" "\n" <sampledata.csv> sampledata2.csv
Esto convertirá cada _single_ DOS-newline en _two_ UNIX-newlines. – Melebius
Super duper easy with PCRE;
Como un script, o reemplace [email protected]
con sus archivos.
#!/usr/bin/env bash
perl -pi -e 's/\r\n/\n/g' -- [email protected]
Esto sobrescribirá sus archivos en su lugar!
solo recomiendo hacer esto con una copia de seguridad (control de versiones o de otra manera)
¡Gracias! Esto funciona, aunque estoy escribiendo el nombre de archivo y no '--'. Elegí esta solución porque es fácil de entender y adaptar para mí. FYI, esto es lo que hacen los conmutadores: '-p' suponen un bucle" while input ",' -i' edit archivo de entrada en su lugar, '-e' ejecutan el siguiente comando – Rolf
Estrictamente hablando, PCRE es una reimplementación de Perl motor regex, no el motor regex de Perl. Ambos tienen esta capacidad, aunque también hay diferencias, a pesar de la implicación en el nombre. – tripleee
TIMTOWTDI!
perl -pe 's/\r\n/\n/; s/([^\n])\z/$1\n/ if eof' PCfile.txt
Basado en @GordonDavisson
se debe considerar la posibilidad de [noeol]
...
Puede usar awk. Establezca el separador de registros (RS
) en una expresión regular que coincida con todos los posibles caracteres o caracteres de nueva línea. Y configure el separador de registro de salida (ORS
) en el carácter de nueva línea al estilo de Unix.
awk 'BEGIN{RS="\r|\n|\r\n|\n\r";ORS="\n"}{print}' windows_or_macos.txt > unix.txt
Eso es lo que funcionó para mí (MacOS, 'git diff' muestra^M, editado en vim) – Dorian
Como una extensión de Unix de Jonathan Leffler a la solución de DOS, para convertir de forma segura a DOS cuando no está seguro de los finales de línea actual del archivo:
sed '/^M$/! s/$/^M/'
Esto comprueba que la línea no hace ya terminar en CRLF antes de convertir a CRLF.
acababa de ponderar la misma pregunta Sorprendentemente nadie mencionó una manera mucho automatizado de hacer CRLF < (en Windows a lado, pero igualmente aplicable a Linux.) -> conversión de LF para archivos de texto usando buena opción edad zip -ll
(Info-ZIP):
zip -ll textfiles-lf.zip files-with-crlf-eol.*
unzip textfiles-lf.zip
NOTA: esto crearía un archivo zip preservar los nombres de los archivos originales, pero la conversión de 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 provocaría sobrescribir 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)
interesante en mi git-bash en ventanas sed ""
hizo el truco ya:
$ 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 el SED los ignora al leer las líneas de entrada y siempre escribe finales de línea Unix en la salida.
Hay un montón de awk/sed/etc respuestas de manera que un suplemento (ya que este es uno de los mejores resultados de búsqueda para este tema):
puede que no tenga dos2unix pero ¿Tiene 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 va en el mismo comando, en todos los archivos .sql de la carpeta actual. -o es el directorio de salida, por lo que puede hacer que reemplace los archivos actuales o, por razones de seguridad/respaldo, enviar a un directorio diferente.
Esto intenta lograr la conversión de codificación de UTF-16LE a UTF-8, pero no toca las terminaciones de línea.No tiene nada que ver con la pregunta que se hace. – Palec
Mi mal. Voy a verificar esto, pero, acabo de utilizar ESE DÍA para solucionar mi problema de grep no se ejecuta en mis archivos porque tenían formato de Windows. –
También es un problema común, pero no el problema que el OP está preguntando (y bastante menos común que el problema CRLF). – tripleee
- 1. jQuery nueva línea \ n
- 2. BASH: Tira carácter de nueva línea de cuerda (leer línea)
- 3. Nueva línea ("\ n") en PHP no funciona
- 4. nueva línea "\ n" en el archivo yaml
- 5. Nueva línea en Node.js
- 6. Cadena de tuberías con nueva línea al comando en bash?
- 7. UNIX: Reemplazar nueva línea w/Colón, La preservación de nueva línea Antes de EOF
- 8. Convierta "\ n" a nueva línea real en SQL Server
- 9. Añade una nueva línea a un NSString
- 10. ¿Por qué "\ n" da una nueva línea en Windows?
- 11. PHP file_put_contents nueva línea
- 12. Cómo usar \ n nueva línea en VB msgbox() ...?
- 13. php :: nueva línea en textarea?
- 14. reemplazar el carácter de nueva línea en la variable bash?
- 15. ¿Hay una línea nueva = \ n OR \ r \ n?
- 16. ¿Cómo ejecutar script bash línea por línea?
- 17. PHP SimpleXML nueva línea
- 18. Bash: ¿Cómo puedo reemplazar una cadena por una nueva línea en osx bash?
- 19. JavaScript nueva línea de caracteres
- 20. Partido de nueva línea '\ n' en rubí expresiones regulares
- 21. GROUP_CONCAT MYSQL nueva línea
- 22. Eliminar nueva línea del final del archivo
- 23. Caracteres nativos de línea nueva?
- 24. nueva línea en FacesMessage Jsf
- 25. NSLog sin línea nueva
- 26. Git: convertir retorno de carro \ r a la nueva línea \ n con git hook?
- 27. ¿Cómo agrego una nueva línea usando printf?
- 28. nueva línea en ensamblaje 8086
- 29. ¿Detener nueva línea enviando un formulario?
- 30. Cómo me uno por la nueva línea
Si puede compilar en el sistema de destino, puede intentar https://github.com/mdolidon/endlines; está hecho para ser bastante portátil. –
En general, simplemente instale 'dos2unix' usando su administrador de paquetes, realmente es mucho más simple y existe en la mayoría de las plataformas. –