【问题标题】:Python help reading csv file failing due to line-endings由于行尾,Python 帮助读取 csv 文件失败
【发布时间】:2011-02-25 05:14:00
【问题描述】:

我正在尝试创建此脚本,该脚本将检查计算机主机名,然后在主列表中搜索该值以在 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 行,在 对于 csv.DictReader(open(fname), 分隔符='\t'): 文件 "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/csv.py", 第 103 行,在下一个 self.fieldnames 文件“/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/csv.py”, 第 90 行,在字段名中 self._fieldnames = self.reader.next() _csv.Error:在未引用的字段中看到换行符 - 你需要打开 通用换行模式下的文件?

当前正在使用的脚本是...

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

【问题讨论】:

    标签: python csv universal line-endings


    【解决方案1】:

    第 194 行和最后一行出现的两次 '\xD5' 与问题无关。

    问题似乎是 Python 2.6 csv 模块中的错误、误导性错误消息或不正确/含糊的文档。

    在文件中,这些行以 Classic Mac 传统中的 '\x0D' 又名 '\r' 终止。最后一行没有终止,但这与问题无关。

    docs for csv.reader 表示“如果 csvfile 是文件对象,则必须在不同的平台上使用‘b’标志打开它。”众所周知,它确实在 Windows 上有所作为。但是,在这种情况下,使用 'rb' 或 'r' 打开文件没有任何区别——仍然是相同的错误消息。

    docs for csv.Dialect.lineterminator 表示“用于终止编写器生成的行的字符串。默认为 '\r\n'。注意:阅读器被硬编码为识别 '\r' 或 '\n'作为行尾,并忽略行终止符。这种行为将来可能会改变。它似乎将 '\r' 识别为换行符,而不是行尾/字段尾。

    错误消息“_csv.Error: new-line character seen in unquoted field - 你需要在通用换行模式下打开文件吗?”令人困惑;它被识别为 '\r' 作为换行符,但它没有将换行符视为行尾(因此隐式地结束了字段)。

    似乎有必要以“rU”模式打开文件以使其“工作”。不清楚为什么在通用换行模式下识别的相同 '\r' 更好。

    【讨论】:

    • 非常有趣。我在打开文件时添加了“rU”模式,它立即工作!我真的很感谢你的帮助。出于某种原因,当我尝试使用 name_to_UID['Aaron-Hoffman.local'] 脚本将运行良好但不输出 uid。但是,如果我尝试其他人,例如 name_to_UID['Beth-Johnson'],它会给我... 回溯(最后一次调用):文件“update.py”,第 6 行,在 name_to_UID['Beth-Johnson. local'] KeyError: 'Beth-Johnson.local'
    • (1) 赞成和接受表示赞赏 (2) 你似乎有两个新问题;开始一个新问题并显示您的脚本和完整的回溯以及显示问题的示例文件(例如 5 行)。否则你只会得到这样的疯狂猜测:新问题 1 是由 name_to_UID['Aaron-Hoffman.local'] (一个被评估然后在不在交互式解释器中时被忽略的表达式)而不是 print name_to_UID['Aaron-Hoffman.local'] 引起的,新问题 2 是由拼写错误引起的
    • 什么是“U”参数?它没有在 Python 文档中列出。
    • @thebossman:它不是“参数”,它是open 内置函数的mode arg 中的补充字符。见上文“以 'rU' 模式打开文件”。阅读 open 文档以了解任何 Python >= 2.3。
    • 感谢您的解释,但我的意思是指mode arg 中的'U'参数。我在 Python 文档中找不到“U”的描述。 “规范”下的这个解释回答了我的问题:python.org/dev/peps/pep-0278
    【解决方案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'
    

    【讨论】:

    • 我不确定我是否理解。 masterlist.txt 有大约 300 行。如何从主机名中提取给定名称的 UID?
    • 好的,我明白你在说什么。所以这会创建一个字典并将它们关联起来。那么我将如何在字典中搜索“名称”?此外,当我尝试运行脚本时似乎遇到了错误错误:在未引用的字段中看到换行符 - 你需要以通用换行模式打开文件吗?
    • @user:我不确定换行符有什么问题,您需要查看文件的实际内容。
    • 简洁,有道理。因此,该文件的名称只是带有分隔 UID 的制表符,然后转到下一行。现在名称确实包含“-”和“。”不确定这是否会影响它。
    • 有没有办法告诉它以“通用换行模式”打开?看起来有些条目也包括数字和括号
    【解决方案3】:

    我会像这样填充字典:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-17
      • 2017-01-03
      • 1970-01-01
      • 1970-01-01
      • 2011-03-24
      • 1970-01-01
      相关资源
      最近更新 更多