Python помогает прочитать CSV-файл с ошибкой из-за окончаний строк

Я пытаюсь создать этот скрипт, который будет проверять имя хоста компьютера, а затем искать в главном списке значение, чтобы вернуть соответствующее значение в файле 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

Прямо сейчас он просто настроен на печать основного списка. Я не уверен, нужно ли анализировать список и помещать его в словарь или что. Мне действительно нужно выяснить, как искать имя хоста в первом поле, а затем возвращать поле во втором столбце.

Заранее спасибо за помощь, Аарон


ОБНОВЛЕНИЕ: я удалил строку 194 и последнюю строку из masterlist.txt, а затем повторно запустил скрипт. Результаты были следующими:

Трассировка (последний последний вызов):
Файл "update.py", строка 3, in for row в csv.DictReader(open(fname), delimiter='\t'): File "/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)

person Aaron    schedule 28.05.2010    source источник


Ответы (3)


Два вхождения '\xD5' в строке 194 и в последней строке не имеют ничего общего с проблемой.

Проблема выглядит как ошибка, или вводящее в заблуждение сообщение об ошибке, или неправильная/расплывчатая документация в модуле csv Python 2.6.

В файле строки заканчиваются символом '\x0D', также известным как '\r' в традиции классического Mac. Последняя строка не завершается, но это не имеет отношения к проблеме.

В документах для csv.reader говорится: "Если csvfile является файловым объектом, он должен быть открыт с флагом «b» на платформах, где это имеет значение». Широко известно, что это имеет значение для Windows. Однако открытие файла с помощью «rb» или «r» в этом случае не имеет значения — сообщение об ошибке остается тем же.

В документах для csv.Dialect.lineterminator говорится: "Используемая строка для завершения строк, созданных модулем записи. По умолчанию используется значение '\r\n'. Примечание. Средство чтения жестко запрограммировано на распознавание '\r' или '\n' в качестве конца строки и игнорирует признак конца строки. Это поведение может измениться в будущем». Кажется, он распознает '\ r' как новую строку, но не как конец строки/конец поля.

Сообщение об ошибке «_csv.Error: в поле без кавычек виден символ новой строки — нужно ли открывать файл в универсальном режиме новой строки?» сбивает с толку; он распознает '\r' как новую строку, но не обрабатывает новую строку как конец строки (и, следовательно, неявно конец поля).

Представляется необходимым открыть файл в режиме «rU», чтобы заставить его «работать». Непонятно, почему тот же '\r', распознаваемый в универсальном режиме новой строки, лучше.

person John Machin    schedule 29.05.2010
comment
Очень интересно. Я добавил режим 'rU' при открытии файла, и он сразу заработал! Я очень ценю вашу помощь в этом. По какой-то причине, когда я пытаюсь использовать name_to_UID['Aaron-Hoffman.local'], скрипт работает нормально, но не выводит uid. Но если я попробую других людей, таких как name_to_UID['Beth-Johnson'], это даст мне... Traceback (последний последний вызов): Файл update.py, строка 6, в ‹module› name_to_UID['Beth-Johnson.local' ] KeyError: «Бет-Джонсон.local» - person Aaron; 29.05.2010
comment
(1) признательность выражается голосованием и принятием (2) у вас, кажется, есть две НОВЫЕ проблемы; задайте НОВЫЙ вопрос и покажите свой сценарий, полную трассировку и файл SAMPLE (скажем, 5 строк), который демонстрирует проблему. В противном случае вы просто получите дикие догадки вроде этого: новая проблема 1 вызвана наличием name_to_UID['Aaron-Hoffman.local'] (выражение, которое оценивается, а затем игнорируется, когда не в интерактивном интерпретаторе) вместо print name_to_UID['Aaron-Hoffman.local'], а новая проблема 2 вызвана опечатками. - person John Machin; 30.05.2010
comment
Что такое параметр «U»? Он не указан в документации Python. - person thebossman; 05.05.2011
comment
@thebossman: это не параметр, это дополнительный символ в аргументе mode встроенной функции open. См. выше, откройте файл в режиме 'rU'. Прочтите open документы для любого Python ›= 2.3. - person John Machin; 05.05.2011
comment
Спасибо за объяснение, но я имел в виду параметр 'U' внутри аргумента mode. Я не смог найти описание «U» в документации по Python. Это объяснение в разделе «Спецификация» отвечает на мой вопрос: python.org/dev/peps/pep -0278 - person thebossman; 05.05.2011

Чтобы перебрать читателя, вы должны сделать:

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

Но так как вы хотите связать Name с UID:

>>> reader = csv.reader(open("masterlist.txt"), delimiter='\t')
>>> _ = next(reader)                                  # just discarding header
>>> d = dict(reader)
>>> d['Carmen-Jackson.local']
'carmenj'
person SilentGhost    schedule 28.05.2010
comment
Я не уверен, что понимаю. В masterlist.txt около 300 строк. Как я могу извлечь UID для данного имени, которое исходит из имени хоста? - person Aaron; 28.05.2010
comment
Хорошо, я понимаю, что вы говорите. Итак, это создает словарь и связывает их. Как мне тогда искать в словаре «Имя»? Кроме того, я, кажется, получаю сообщение об ошибке, когда пытаюсь запустить скрипт Ошибка: символ новой строки виден в поле без кавычек - вам нужно открыть файл в универсальном режиме новой строки? - person Aaron; 28.05.2010
comment
@user: я не уверен, какая у вас проблема с символами новой строки, вам нужно взглянуть на фактическое содержимое вашего файла. - person SilentGhost; 28.05.2010
comment
Аккуратно, в этом есть смысл. Таким образом, файл просто имеет имя с вкладкой, разделяющей UID, а затем переходит к следующей строке. Теперь имя включает - и . не уверен, что это влияет. - person Aaron; 28.05.2010
comment
Есть ли способ сказать, чтобы он открывался в режиме универсальной новой строки? Похоже, что некоторые записи также включают числа и скобки. - person Aaron; 28.05.2010
comment
@user: я не слежу за тобой. Не могли бы вы опубликовать образец содержимого файла? - person SilentGhost; 28.05.2010
comment
Есть ли способ выложить файл? Или прикрепить? Я новичок в этом и не знаю, как это сделать. Вероятно, вам будет лучше взглянуть на настоящий файл. - person Aaron; 29.05.2010
comment
@user: у меня нет никаких проблем с вашим файлом. В строке 37-38 у вас есть повторяющиеся записи, но это все. Это не влияет на код. - person SilentGhost; 29.05.2010
comment
@user: есть проблема с файлом, но я думаю, что единственное, что ее вызывает, - это странные символы в строке 194 и последней строке. Кажется, он не закодирован в utf-8. Просто удалите/исправьте его, и все будет хорошо. - person SilentGhost; 29.05.2010
comment
Не могли бы вы взглянуть на обновление, которое я добавил в пост? Я включил результат выполнения скрипта после того, как эти строки были удалены из мастер-листа, а также текущий скрипт. - person Aaron; 29.05.2010
comment
@SilentGhost: Кажется?? Он определенно не закодирован в utf-8. В любом случае проблема не в этом. Смотрите мой ответ. - person John Machin; 29.05.2010

Я бы заполнил словарь следующим образом:

>>> 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'
person taleinat    schedule 28.05.2010