tags:

views:

196

answers:

3

I'm trying to create this script that will check the computer host name then search a master list for the value to return a corresponding value in the csv file. Then open another file and do a find an replace. I know this should be easy but haven't done so much in python before. Here is what I have so far...

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

Here is the script that I have created thus far

#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

Right now, it's just set to print the master list. I'm not sure if the list needs to be parsed and placed into a dictionary or what. I really need to figure out how to search the first field for the hostname and then return the field in the second column.

Thanks in advance for your help, Aaron


UPDATE: I removed line 194 and last line from masterlist.txt and then re-ran the script. The results were the following:

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?

The current script being used is...

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

To get iterate over a reader you'd do:

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

But since you want to associate Name with UID:

>>> reader = csv.reader(open("masterlist.txt"), delimiter='\t')
>>> _ = next(reader)                                  # just discarding header
>>> d = dict(reader)
>>> d['Carmen-Jackson.local']
'carmenj'
SilentGhost
I'm not sure I understand. The masterlist.txt has about 300 rows. How can I extract the UID for a given Name that comes from the host name?
Aaron
@user: see my edit
SilentGhost
Ok, I see what you're saying. So this creates a dictionary and associates them. How would I then go about searching the dictionary for the 'Name'?Also, I seem to be getting an error when I try to run the scriptError: new-line character seen in unquoted field - do you need to open the file in universal-newline mode?
Aaron
@user: I'm not sure what issue you have with the new-line characters, you'd need to have a look at the actual content of your file.
SilentGhost
Neat, that makes sense. So the file just has the name with a tab seperating the UID and then goes to the next line. Now the name does include a "-" and "." not sure if this effects it.
Aaron
Is there are way to tell it to open in "universal-newline mode"? Looks like some entries include Numbers and Parenthesis too
Aaron
@user: I'm not following you. Could you post a sample of the file content?
SilentGhost
Is there a way to post the file? Or attach it? I'm sort of new to this and not sure how to do it. It would probably be better for you to take a look at the actual file.
Aaron
Please see the master list here: http://www.queencitytech.com/masterlist.txt
Aaron
@user: I don't have any issues with your file whatsoever. One the line 37-38 you have duplicate records, but that's about it. It doesn't affect the code.
SilentGhost
@user: there is an issue with the file, but I think the only thing that causes it is the strange characters on the line 194 and the last line. It doesn't seem to be encoded in utf-8. Just remove/fix it and everything will be fine.
SilentGhost
Can you please take a look at the Update I added to the post? I included the result from running script after those lines were removed from masterlist as well as the current script.
Aaron
@SilentGhost: Seems?? It's definitely not encoded in utf-8. In any case that's not the problem. See my answer.
John Machin
A: 

I would populate a dictionary like this:

>>> 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'
taleinat
A: 

The two occurrences of '\xD5' in line 194 and the last line have nothing to do with the problem.

The problem appears to be a bug, or a misleading error message, or incorrect/vague documentation, in the Python 2.6 csv module.

In the file, the lines are terminated by '\x0D' aka '\r' in the Classic Mac tradition. The last line is not terminated, but that is nothing to do with the problem.

The docs for csv.reader say "If csvfile is a file object, it must be opened with the ‘b’ flag on platforms where that makes a difference." It is widely known that it does make a difference on Windows. However opening the file with 'rb' or 'r' makes no difference in this case -- still the same error message.

The docs for csv.Dialect.lineterminator say "The string used to terminate lines produced by the writer. It defaults to '\r\n'. Note: The reader is hard-coded to recognise either '\r' or '\n' as end-of-line, and ignores lineterminator. This behavior may change in the future." It appears to be recognising '\r' as new-line but not as end-of-line/end-of-field.

The error message "_csv.Error: new-line character seen in unquoted field - do you need to open the file in universal-newline mode?" is confusing; it's recognised '\r' as a new-line, but it's not treating new-line as an end-of line (and thus implicitly end-of-field).

It appears necessary to open the file in 'rU' mode to get it to "work". It's not apparent why the same '\r' recognised in universal-newline mode is any better.

John Machin
Very interesting. I added the 'rU'mode when opening the file and it worked right away! I really appreciate your help with that. For some reason, when I try to use name_to_UID['Aaron-Hoffman.local'] the script will run fine but doesn't output the uid. But if I try other people like name_to_UID['Beth-Johnson'] it gives me...Traceback (most recent call last): File "update.py", line 6, in <module> name_to_UID['Beth-Johnson.local']KeyError: 'Beth-Johnson.local'
Aaron
(1) appreciation is shown by up-voting and accepting (2) you seem to have two NEW problems; start a NEW question and show your script and the full traceback and a SAMPLE file (say 5 lines) that exhibits the problem. Otherwise you will just get wild guesses like this: new problem 1 is caused by having `name_to_UID['Aaron-Hoffman.local']` (an expression which is evaluated and then ignored when not in the interactive interpreter) instead of `print name_to_UID['Aaron-Hoffman.local']` and new problem 2 is caused by typos
John Machin