Zimbra zmprov 格式的文件到 csv 和 ldif

Zimbra zmprov formatted file to csv and ldif

我正在学习 python,我的第一个作业是将 Zimbra zmprov 格式的文件转换为 csvldif.

因为我不知道 python 内置函数来完成任务,所以我走了很长一段路,遍历行并打印。

如果你们能告诉我如何正确地做,我将不胜感激。

这是输入zmp_file,要转换成csv和ldif

ca user1@domain.com.br      ''
ma user1@domain.com.br cn   'User One'
ma user1@domain.com.br cpf  ''
ma user1@domain.com.br l    'Porto Alegre'

ca user2@domain.com.br      ''
ma user2@domain.com.br cn   'User Two'
ma user2@domain.com.br cpf  '0123456789'
ma user2@domain.com.br l    ''

所需的 .csv 输出(字段顺序不重要)

mail,cn,cpf,l
user1@domain.com.br,"User One",,"Porto Alegre"
user2@domain.com.br,"User Two",0123456789,

以及所需的 .ldif 输出(字段的顺序并不重要)

dn:   'uid=user1@domain.com.br'
cn:   'User One'
l:    'Porto Alegre'
mail: 'user1@domain.com.br'

dn:   'uid=user2@domain.com.br'
cn:   'User Two'
cpf:  '0123456789'
mail: 'user2@domain.com.br'

我能走多远:

with zmp_file as input_file
    for line in input_file:
        if line.startswith('ca'):
            mail = line.split()[1]
            print "dn: uid={0}".format(mail)
            print "mail: {0}".format(mail)
        elif line.startswith('ma'):
            words = shlex.split(line)[-2:]
            print "{0}: {1}".format(words[0], words[1])
        else:
            print

您可以使用 regexpandas:

zmprov 转换为 csvldif
import re
import pandas as pd

with open('file.txt', 'r') as f:
    data = f.read()

mail = re.findall('ca (\S+)', data)
cn = re.findall('cn +(.*)', data)
cpf = re.findall('cpf + (.*)', data)
l = re.findall('l + (.*)', data)

df = pd.DataFrame({'mail': mail, 'cn': cn, 'cpf': cpf, 'l': l})
df.to_csv('file.csv', sep=',', encoding='utf-8', index=False)

with open('file.ldif', 'w') as f:
    for m_, cn_, cpf_, l_ in zip(mail, cn, cpf, l):
        if re.findall('\w+', l_):
            f.write("""dn:   'uid={m}'\ncn:   {cn}\nl:    {l}\nmail: '{m}'\n\n""".format(m=m_, cn=cn_, l=l_))
        elif cpf_:
            f.write("""dn:   'uid={m}'\ncn:   {cn}\ncpf:  {cpf}\nmail: '{m}'\n\n""".format(m=m_, cn=cn_, cpf=cpf_))

输出file.csv:

mail,cn,cpf,l
user1@domain.com.br,'User One','','Porto Alegre'
user2@domain.com.br,'User Two','0123456789',''

输出file.ldif:

dn:   'uid=user1@domain.com.br'
cn:   'User One'
l:    'Porto Alegre'
mail: 'user1@domain.com.br'

dn:   'uid=user2@domain.com.br'
cn:   'User Two'
cpf:  '0123456789'
mail: 'user2@domain.com.br'

好的。知道了

我知道这不是codereview.stackexchange.com,但如果有人有意见,我在这里学习。

#!/usr/bin/env python

import csv
import os
import shlex
import sys
from ldif import LDIFParser, LDIFWriter

def zmp_to_csv_and_ldif(zmp_file):

    all_attrs = set()
    data      = {}
    records   = {}

    with zmp_file as input_file:
        for line in input_file:
            if line.startswith('ca'):
                cmd, mail, pwd       = line.split()
                data['mail']         = mail
                data['userpassword'] = pwd
                records[mail]        = data
                all_attrs.update(['mail','userpassword'])
            elif line.startswith('ma'):
                cmd, mail, attr, value = shlex.split(line)
                data[attr]             = value
                records[mail]          = data
                all_attrs.add(attr)
            else:
                data = {}

    with open('/tmp/rag-parsed.csv', 'w') as output_file:
        csv_writer = csv.DictWriter(output_file, fieldnames=all_attrs, extrasaction='ignore', lineterminator='\n')
        csv_writer.writeheader()
        for mail, data in sorted(records.items()):
            csv_writer.writerow(data)

    with open('/tmp/rag-parsed.ldif', 'w') as output_file:
        b64_attrs   = map(str.lower, ['jpegPhoto', 'userPassword'])
        ldif_writer = LDIFWriter(output_file, base64_attrs=b64_attrs, cols=999)
        for mail, data in sorted(records.items()):
            dn = "uid={0}".format(mail)
            data_in_ldap_fmt = dict([k, v.split('\n')] for k, v in data.items() if v)
            ldif_writer.unparse(dn, data_in_ldap_fmt)