2010-05-09 22 views
8

Tengo un montón de archivos. Algunos son terminaciones de línea Unix, muchos son DOS. Me gustaría probar cada archivo para ver si está formateado dos, antes de cambiar las terminaciones de línea.¿Cómo puedo detectar saltos de línea DOS en un archivo?

¿Cómo podría hacer esto? ¿Hay una bandera que pueda probar? ¿Algo parecido?

+0

La misma pregunta como http: // stackoverflow.com/questions/121392/how-to-determine-the-line-ending-of-a-file (excepto la etiqueta 'python' :-) – Jonik

Respuesta

6

Puede buscar la cadena \r\n. Ese es el final de línea estilo DOS.

EDIT: Tome un vistazo a this

+0

Sí, este es el camino a seguir. No hay bandera ni nada. – Jonik

+0

Técnicamente, busca '" \ r \ x0A "'. La mayoría de los compiladores usan el avance de línea para ''\ n'', pero no es necesario que tenga ese valor particular. –

0

dos saltos de línea son \r\n, sólo UNIX \n. Así que solo busca \r\n.

1

Como un completo novato de Python & solo por diversión, traté de encontrar alguna forma minimalista de verificar esto para un archivo. Esto parece funcionar:

if "\r\n" in open("/path/file.txt","rb").read(): 
    print "DOS line endings found" 

Editar: simplificada de acuerdo con el comentario de John Machin (sin necesidad de utilizar expresiones regulares).

+0

¿No debería abrir el archivo con "rb"? –

+0

Hmm, mi primer pensamiento fue no, porque estamos tratando con archivos * text * ... ¿Te refieres a esto? "El valor predeterminado es usar el modo de texto, que puede convertir '\ n' caracteres a una plataforma- representación específica en la escritura y de vuelta en la lectura ". (http://docs.python.org/library/functions.html#open)? No estaba al tanto de tales conversiones, tal vez "rb" debería utilizarse para que esto también funcione en sistemas que no sean de Unix. – Jonik

+2

're.search()' no es minimalista; es OVERKILL; use '" \ r \ n "en open (...). read()'. No hay "tal vez" sobre usar '" rb "'; es un deber. –

3

(Python 2 única :) Si lo que desea es leer archivos de texto, ya sea DOS o Unix con formato, esto funciona:

print open('myfile.txt', 'U').read() 

Es decir, lector de archivos de Python "universal" utilizará automáticamente todos los diferentes marcadores de final de línea, traduciéndolos a "\ n".

http://docs.python.org/library/functions.html#open

(Gracias manejan!)

+1

Bueno, querré editarlos en vim. Me gustaría hacer que ese final de línea cambie una vez y confirmarlo, vs por archivo. – chiggsy

+2

Esto cambiará destructivamente DOS CRLF a Unix LF en todos los archivos en el directorio actual: perl -p0i -e 's/\ r \ n/\ n/g' * He tipeado esto tantas veces los dedos lo han memorizado :) – johntellsall

+0

@chiggsy instale el paquete dos2unix, y ejecute el comando dos2unix en los archivos en su lugar. – nos

22

Python puede detectar automáticamente qué convención de nueva línea se utiliza en un archivo, gracias al "modo de salto de línea universal" (U), y se puede acceder Python adivinar a través del atributo newlines de objetos de archivo:

f = open('myfile.txt', 'U') 
f.readline() # Reads a line 
# The following now contains the newline ending of the first line: 
# It can be "\r\n" (Windows), "\n" (Unix), "\r" (Mac OS pre-OS X). 
# If no newline is found, it contains None. 
print repr(f.newlines) 

Esto le da al final de nueva línea de la primera línea (Unix, DOS, etc.), si alguna.

Como señaló John M., si por casualidad tiene un archivo patológico que utiliza más de una nueva línea de codificación, f.newlines es una tupla con todas las codificaciones de nueva línea encontradas hasta el momento, después de leer muchas líneas.

Referencia: http://docs.python.org/2/library/functions.html#open

Si sólo desea convertir un archivo, sólo tiene que hacer:

with open('myfile.txt', 'U') as infile: 
    text = infile.read() # Automatic ("Universal read") conversion of newlines to "\n" 
with open('myfile.txt', 'w') as outfile: 
    outfile.write(text) # Writes newlines for the platform running the program 
+1

-1 Se llama' newlines' (plural) y no es una codificación. Lo que ha mostrado es cómo encontrar qué (si acaso) termina la primera línea (si la hay). Su comentario es incorrecto: no incluye el caso en el que la primera línea y la única línea no se termina (por lo que 'newlines' se refiere a' None'). Además, asume que todas las líneas se terminan de la misma manera. Las concatenaciones de archivos de diferentes terminaciones de línea no son desconocidas. En la aplicación del OP de estandarización en el final de una línea, deberá leer TODO el archivo de entrada (y TODOS los documentos, especialmente donde se menciona 'tuple'). –

+2

@John: Vamos: -1 para una respuesta que menciona las 'nuevas líneas' útiles, pero solo con un error tipográfico? ¿O para archivos patológicos concatenados de archivos con diferentes convenciones de nueva línea? El cartel original mencionaba "archivos de Unix o DOS", ¡no archivos tan extraños! – EOL

+0

@John: Su información sobre f.newlines devolver una tupla en el caso de una convención de nueva línea mixta es interesante. Lo agregué a la respuesta. – EOL

0

El uso de grep & bash:

grep -c -m 1 $'\r$' file 

echo $'\r\n\r\n' | grep -c $'\r$'  # test 

echo $'\r\n\r\n' | grep -c -m 1 $'\r$' 
Cuestiones relacionadas