【问题标题】:Python 3 reading comma delimited CSV file manipulating variable and writing out to CSVPython 3读取逗号分隔的CSV文件操作变量并写出CSV
【发布时间】:2015-05-01 02:32:54
【问题描述】:

我是 Python 新手,希望读取包含以下内容的 CSV 文件:

DN, whenCreated, name, pwdLastSet, location
"CN=Jackson2,OU=Domain Controllers,DC=one,DC=onecity,DC=net",20100623145323.0Z,Jackson8,1.30745E+17,Japan,
"CN=Jackson4,OU=Prod,OU=Windows 2014 Servers,OU=STE,DC=one,DC=onecity,DC=net",20041208192730.0Z,Jackson7,1.30735E+17,Aussie,

这个 CSV 文件将有数千行长,我想将所有字段输出到一个新的 CSV 文件,并将 whenCreatedpwdLastSet 字段更改为人类可读的格式。任何意见,将不胜感激。请注意,本例中有 5 列 3 行,第一行是列标题。

所以放轻松,因为这是我编写的第一个 python 脚本。但任何建议、cmets、最佳实践将不胜感激。

    import csv
    import sys
    import time
    from datetime import datetime

    def adTimestampToUnix(ad):
        #Convert an 18-digit Windows NT timestamp to a UNIX timestamp
        return int(((ad / 10000000) - 11644473600))
    import datetime

    file = open("source.csv", 'rt')
    fileWrite = open("target.csv", 'w', newline='')
    try:
        csvFile = csv.reader(file)
        csvWrite = csv.writer(fileWrite, dialect='excel')
        for row in csvFile:
            csvWrite.writerow(row)
            for row in csvFile:
                whenCreated = row[1]
                year = whenCreated[:4]
                month = whenCreated[4:6]
                day = whenCreated[6:8]
                hour = whenCreated[8:10]
                minute = whenCreated[10:12]
                seconds = whenCreated[12:14]
                whenCreated =(month+"/"+day+"/"+year+" "+hour+":"+minute+":"+seconds)
                pwdLastSet = int(row[3])
                pwdLastSet = adTimestampToUnix(pwdLastSet)
                if pwdLastSet < 1:
                    pwdLastSet = ""
                else:
                    pwdLastSet = datetime.datetime.utcfromtimestamp(pwdLastSet).strftime('%Y-%m-%d %H:%M:%S')
                row = (row[0],whenCreated,row[2],pwdLastSet,row[4])
                csvWrite.writerow(row)
    finally:
        file.close()

【问题讨论】:

  • 你能把你写的东西贴出来吗?如果您还没有写任何东西,作为提示,请从 CSV 模块开始。
  • 将您在 cmets 中的代码放入问题中。它会帮助别人帮助你。

标签: python csv active-directory largenumber


【解决方案1】:

正如您问题的第一条评论中所述,csv 模块将负责 CSV 文件的基本读写。使用第一个example

import csv
with open('some.csv', newline='') as f:
    reader = csv.reader(f)
    for row in reader:
        print(row)

您的 CSV 文件向我们展示了 csv.reader 会将文件中的每一行转换为字符串列表

['DN',' whenCreated',' name',' pwdLastSet',' location']
['"CN=Jackson2,OU=Domain Controllers,DC=one,DC=onecity,DC=net"','20100623145323.0Z','Jackson8','1.30745E+17','Japan','']

同样,csv.writer 将获取一个值列表并将其写入输出文件中的一行。

简单。

所以,您问题中真正有趣的部分是:

I) 修复第一行(列标题)

请注意,第一个列表中的大多数列名都有一个前导空格。我们想摆脱这些,因为它们可能是有问题的。如果您使用过其他语言,您可能会考虑使用循环,例如

for i in range(len(row)):
    row[i] = row[i].strip()

然而,在 Python 中,首选形式是使用“列表理解”,

row = [x.strip() for x in row]

II) 将whenCreated 转换为“人类可读的格式”。

确实是这样,但是一些破折号和冒号会将其转换为 ISO 8601 日期格式,所以让我们使用这样的字符串对象的 .format 方法

x = row[1]
row[1] = '{}-{}-{}T{}:{}:{}'.format(x[:4],x[4:6],x[6:8],x[8:10],x[10:12],x[12:])

从这个转换row[1] ...

20100623145323.0Z

...到这个:

2010-06-23T14:53:23.0Z

III) 将pwdLastSet 转换为“人类可读的格式”。

我从您更新的问题中看到,这些数字是 18 位 Active Directory 时间戳(以科学记数法表示),所以您完全正确,我们可以使用 datetime 来转换它们

from datetime import datetime
row[3] = datetime.utcfromtimestamp(float(row[3])/10000000-11644473600).isoformat() + 'Z'

将从此转换row[3] ...

1.30745E+17

...到这个:

2015-04-26T05:33:20Z

【讨论】:

  • 只是好奇 - 使用这种方法,您需要担心第一行(标题行),还是 csv 解析器知道跳过它?我注意到您没有任何逻辑来避免第一种情况 row[1] = "whenCreated"
  • @RandyBanks - 是的,如果我们知道(或可以确定)第一行包含列标题,我们的代码需要显式处理第一行。例如,我们不想尝试对像“pwdLastSet”这样的字符串进行日期时间转换,因为它显然不起作用。
  • 感谢上帝!欣赏它
猜你喜欢
  • 1970-01-01
  • 2016-12-08
  • 1970-01-01
  • 2018-06-01
  • 1970-01-01
  • 2015-03-19
  • 2020-03-20
  • 2016-04-22
  • 1970-01-01
相关资源
最近更新 更多