Python读取csv文件因行结束符失败的帮助

8 投票
3 回答
10987 浏览
提问于 2025-04-15 23:17

我正在尝试创建一个脚本,这个脚本会检查电脑的主机名,然后在一个主列表中查找对应的值,并返回一个CSV文件中的相关值。接着,它会打开另一个文件,进行查找和替换。我知道这应该很简单,但我之前在Python方面的经验不多。以下是我目前的进展……

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

这是我到目前为止创建的脚本

#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

现在,它只是设置为打印主列表。我不确定这个列表是否需要解析并放入一个字典中,或者该怎么做。我真的需要弄清楚如何在第一列中搜索主机名,然后返回第二列中的字段。

提前感谢你的帮助,
亚伦


更新:我删除了masterlist.txt中的第194行和最后一行,然后重新运行了脚本。结果如下:

追踪(最近的调用最后):
文件 "update.py",第3行,
for row in csv.DictReader(open(fname),
delimiter='\t'): 文件
"/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/csv.py",
第103行,next
self.fieldnames 文件 "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/csv.py",
第90行,fieldnames
self._fieldnames = self.reader.next()
_csv.Error: 在未加引号的字段中发现换行符 - 你是否需要以通用换行模式打开文件?

当前使用的脚本是……

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

3 个回答

2

如果你想要遍历一个读取器,你可以这样做:

>>> 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'}

但是因为你想把 NameUID 关联起来:

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

我想像这样填充一个字典:

>>> 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

在第194行和最后一行出现的两个'\xD5'和这个问题没有关系。

这个问题看起来是Python 2.6的csv模块里的一个bug,或者是一个误导性的错误信息,或者是文档不准确/模糊。

在这个文件中,行的结束符是'\x0D',也就是经典Mac系统中的'\r'。最后一行没有结束符,但这和问题没有关系。

csv.reader的文档上说:“如果csvfile是一个文件对象,它必须在需要时用‘b’标志打开。”大家都知道在Windows上确实有区别。不过在这个情况下,用'rb'或者'r'打开文件没有任何区别——错误信息还是一样。

csv.Dialect.lineterminator的文档上说:“用于结束写入的行的字符串。默认是'\r\n'。注意:读取器是硬编码的,识别'\r'或'\n'作为行结束符,并忽略lineterminator。这个行为将来可能会改变。”看起来它把'\r'识别为新行,但没有把新行当作行结束(因此也就不是字段结束)。

错误信息“_csv.Error: 在未加引号的字段中看到新行字符 - 你是否需要以通用新行模式打开文件?”让人困惑;它把'\r'识别为新行,但没有把新行当作行结束(也就是隐含的字段结束)。

似乎必须以'rU'模式打开文件才能让它“正常工作”。不太明白为什么在通用新行模式下识别的'\r'会更好。

撰写回答