2010-05-28 11 views
8

Estoy tratando de crear este script que verifique el nombre de host de la computadora y busque en una lista maestra el valor para devolver un valor correspondiente en el archivo csv. Luego abre otro archivo y haz un buscar y reemplazar. Sé que esto debería ser fácil, pero no he hecho tanto en Python antes. Aquí es lo que tengo hasta ahora ...Python help reading csv file failed by line-endings

masterlist.txt (tab delimited) 
Name     UID 
Bob-Smith.local  bobs 
Carmen-Jackson.local carmenj 
David-Kathman.local davidk 
Jenn-Roberts.local jennr 

aquí es el guión que he creado hasta ahora

#GET CLIENT HOST NAME 
import socket 
host = socket.gethostname() 
print host 

#IMPORT MASTER DATA 
import csv, sys 
filename = "masterlist.txt" 
reader = csv.reader(open(filename, "rU")) 

#PRINT MASTER DATA 
for row in reader: 
    print row 

#SEARCH ON HOSTNAME AND RETURN UID 



#REPLACE VALUE IN FILE WITH UID 
#import fileinput 
#for line in fileinput.FileInput("filetoreplace",inplace=1): 
# line = line.replace("replacethistext","UID") 
# print line 

En este momento, es simplemente ajustada para imprimir la lista maestra. No estoy seguro de si la lista debe analizarse y colocarse en un diccionario o qué. Realmente tengo que encontrar la manera de buscar el primer campo para el nombre de host y luego regresar al campo en la segunda columna.

Gracias de antemano por su ayuda, Aaron


ACTUALIZACIÓN: Me quita la línea 194 y la última línea de MasterList.txt y vuelva a ejecutar el script. Los resultados fueron los siguientes:

Traceback (most recent call last):
File "update.py", line 3, in for row in csv.DictReader(open(fname), delimiter='\t'): File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/csv.py", line 103, in next self.fieldnames File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/csv.py", line 90, in fieldnames self._fieldnames = self.reader.next() _csv.Error: new-line character seen in unquoted field - do you need to open the file in universal-newline mode?

El script actual que se utiliza es ...

import csv 
fname = "masterlist.txt" 
for row in csv.DictReader(open(fname), delimiter='\t'): 
    print(row) 

Respuesta

2

Para iterar sobre un lector que haría:

>>> import csv 
>>> for row in csv.DictReader(open(fname), delimiter='\t'): 
    print(row) 


{'Name': 'Bob-Smith.local', 'UID': 'bobs'} 
{'Name': 'Carmen-Jackson.local', 'UID': 'carmenj'} 
{'Name': 'David-Kathman.local', 'UID': 'davidk'} 
{'Name': 'Jenn-Roberts.local', 'UID': 'jennr'} 

Pero ya que desea asociar Name con UID:

>>> reader = csv.reader(open("masterlist.txt"), delimiter='\t') 
>>> _ = next(reader)         # just discarding header 
>>> d = dict(reader) 
>>> d['Carmen-Jackson.local'] 
'carmenj' 
+0

No estoy seguro de entender. El archivo masterlist.txt tiene alrededor de 300 filas. ¿Cómo puedo extraer el UID para un Nombre dado que proviene del nombre de host? – Aaron

+0

@usuario: vea mi edición – SilentGhost

+0

Ok, veo lo que está diciendo. Esto crea un diccionario y los asocia. Luego, ¿sigo buscando en el diccionario el 'Nombre'? Además, parece que recibo un error cuando intento ejecutar el secuencia de comandos Error: carácter de nueva línea visto en el campo sin comillas: ¿necesita abrir el archivo en modo de nueva línea universal? – Aaron

2

que sería llenar un diccionario de la siguiente manera:

>>> import csv 
>>> name_to_UID = {} 
>>> for row in csv.DictReader(open(filename, 'rU'), delimiter='\t'): 
    name_to_UID[row['Name']] = row['UID'] 
>>> name_to_UID['Carmen-Jackson.local'] 
'carmenj' 
20

Los dos apariciones de '\ xd5' en la línea 194 y la última línea no tienen nada que ver con el problema.

El problema parece ser un error o un mensaje de error equivocado, o documentación incorrecta/vaga, en el módulo csv Python 2.6.

En el archivo, las líneas están terminadas en '\ x0D' aka en la tradición clásica de Mac '\ r'. La última línea no está terminada, pero eso no tiene nada que ver con el problema.

docs for csv.reader dice "Si csvfile es un objeto de archivo, debe abrirse con la bandera 'b' en plataformas donde eso hace la diferencia." Es ampliamente conocido que hace una diferencia en Windows. Sin embargo abrir el archivo con 'rb' o 'r' no hace ninguna diferencia en este caso - sigue siendo el mismo mensaje de error.

docs for csv.Dialect.lineterminator dice "La cadena utilizada para terminar las líneas producidas por el escritor. Por defecto es '\ r \ n'. Nota: El lector está codificado para reconocer '\ r' o '\ n' como de final de línea, e ignora lineterminator. Este comportamiento puede cambiar en el futuro ". Parece reconocer '\ r' como nueva línea pero no como final de línea/fin de campo.

El mensaje de error "_csv.Error: carácter de nueva línea visto en el campo sin comillas - ¿necesita abrir el archivo en modo universal-nueva línea?"es confuso; se reconoce '\ r' como una nueva línea, pero no trata la línea nueva como un final de línea (y por lo tanto implícitamente al final del campo).

Parece necesario abrir el archivo en modo 'rU' para hacer que funcione. No es evidente por qué el mismo '\ r' reconocido en el modo universal-nueva línea es mejor.

+1

Muy interesante. ¡Agregué el modo 'rU' al abrir el archivo y funcionó de inmediato! Realmente aprecio tu ayuda con eso. Por alguna razón, cuando trato de usar name_to_UID ['Aaron-Hoffman.local'] la secuencia de comandos se ejecutará bien, pero no emite el uid. Pero si pruebo a otras personas como name_to_UID ['Beth-Johnson'] me da ... Traceback (última llamada más reciente): Archivo "update.py", línea 6, en name_to_UID ['Beth- Johnson.local '] KeyError:' Beth-Johnson.local ' – Aaron

+0

(1) la apreciación se muestra al votar y aceptar (2) parece que tiene dos problemas NUEVOS; comience una NUEVA pregunta y muestre su secuencia de comandos y el rastreo completo y un archivo SAMPLE (digamos 5 líneas) que muestra el problema. De lo contrario, obtendrás conjeturas alocadas como esta: el nuevo problema 1 es causado por tener 'name_to_UID ['Aaron-Hoffman.local']' (una expresión que se evalúa y luego se ignora cuando no está en el intérprete interactivo) en lugar de 'print name_to_UID ['Aaron-Hoffman.local'] 'y el nuevo problema 2 es causado por errores tipográficos –

+0

¿Qué es el parámetro 'U'? No aparece en los documentos de Python. – thebossman