2010-02-02 21 views
11

Tengo un archivo de texto muy largo que estoy tratando de procesar usando Python.Python cree que un archivo de texto de 3000 líneas tiene una línea de longitud?

Sin embargo, el siguiente código:

for line in open('textbase.txt', 'r'): 
    print 'hello world' 

sólo produce el siguiente resultado:

hello world 

Es como si Python cree que el archivo es sólo una línea larga, aunque es muchos miles de líneas de largo, cuando se ve en un editor de texto. Examinándola en la línea de comandos utilizando el comando archivo da:

$ file textbase.txt 
textbase.txt: Big-endian UTF-16 Unicode English text, with CR line terminators 

Sucede algo? ¿Debo cambiar los terminadores de línea?

+0

¿Qué sistema operativo estás? –

+0

@OP, ¿de dónde viene textbase.txt? ventanas? intente hacer un dos2unix en el archivo y vea que resuelve el problema – ghostdog74

+0

@jldupont: Creo que AP257 esperaba imprimir "hello world" para cada línea del archivo de entrada, tal como dice el código :-) – paxdiablo

Respuesta

6

Probablemente descubrirá que es el "con terminadores de línea CR" lo que le da la partida al juego. Si está trabajando en una plataforma que usa líneas nuevas como terminadores de línea, será y verá su archivo como una gran línea honkin '.

Cambie su archivo de entrada para que utilice los terminadores de línea correctos. Tu editor probablemente sea más indulgente que tu implementación de Python.

Las terminaciones de línea CR son una cosa de Mac hasta donde yo sé y puede usar el modificador de modo U en open para autodetectar en función del terminador de primera línea encontrado.

+0

'Nail + head' combo me piensa. +1. –

+0

Gracias. ¿Alguna idea de a qué tengo que cambiarlos? – AP257

+0

Yo diría '\ n'. –

-1

open() devuelve un objeto de archivo. Es necesario utilizar:

for line in open('textbase.txt', 'r').readlines(): 
    print line 
+2

Esto no es necesario, ya que el objeto de archivo abierto se comporta como un iterador. –

+0

Hace la diferencia, lo siento ... – AP257

+0

Ah ... buen punto. No lo había apreciado. – Paul

25

De acuerdo con la documentation for open(), se debe añadir un U al modo:

open('textbase.txt', 'Ur') 

Esto permite "universal newlines", lo que les normaliza a \n en las cadenas que te da .

Sin embargo, lo correcto es decodificar el UTF-16BE en objetos Unicode primero, antes de traducir las nuevas líneas. De lo contrario, un byte oportunidad 0x0d podría conseguir erróneamente convertido en un 0x0a, lo que resulta en

UnicodeDecodeError: 'utf16' codec can't decode byte 0x0a in position 12: truncated data.

de codecs module suministra una función open que puede decodificar Unicode y manejar los saltos de línea, al mismo tiempo Python:

import codecs 
for line in codecs.open('textbase.txt', 'Ur', 'utf-16be'): 
    ... 

Si el el archivo tiene una marca de orden de bytes (BOM) y usted especifica 'utf-16', luego detecta el endianness y oculta la lista de materiales por usted. Si no lo hace (dado que la lista de materiales es opcional), entonces ese decodificador simplemente continuará y usará la endianidad de su sistema, lo que probablemente no sea bueno.

Especificación del orden de bits a sí mismo (con 'utf-16be') no ocultará la lista de materiales, por lo que es posible que desee utilizar este truco:

import codecs 
firstline = True 
for line in codecs.open('textbase.txt', 'Ur', 'utf-16be'): 
    if firstline: 
     firstline = False 
     line = line.lstrip(u'\ufeff') 

Ver también: Python Unicode HOWTO

+0

+1 para la solución en lugar de solo el análisis (como en mi respuesta) - fuiste demasiado rápido para mí :-) – paxdiablo

+0

Resuelve el problema, python ahora ve todas las líneas. Muchas gracias: me encanta este sitio :) – AP257

+1

@ AP257: ¿también decodifican correctamente? Si es realmente UTF-16BE, habrá un byte cero delante de cada línea, ya que el objeto de archivo de Python está codificando-inconsciente y simplemente se divide en caracteres de nueva línea. En mi humilde opinión, deberá decodificar el archivo (utilizando el módulo de códecs) correctamente antes de dividirlo en líneas. –

Cuestiones relacionadas