代码之家  ›  专栏  ›  技术社区  ›  Karn Kumar

python搜索以模式dn开头的行并用oteh子模式打印下两行

  •  1
  • Karn Kumar  · 技术社区  · 6 年前

    我有一个原始文件,其中有一些数据,但是我只想要一些相关的数据,如果行startswith模式 ^dn 遵循子模式 AccessFTPexpire ftpUser 然后打印这些行并跳过/忽略其他行。

    下面是我的原始数据文件:

    $ cat ftpdata
    dn: uid=dev-ftp,ou=ftpusers,ou=applications,o=regg.com
    dn: uid=dev-ftp,ou=ftpusers,ou=applications,o=regg.com
    dn: uid=case_101,ou=ftpusers,ou=applications,o=regg.com
    AccessFTPexpire: 05/03/2017
    ftpUser: T
    dn: uid=test-ftp,ou=ftpusers,ou=applications,o=regg.com
    ftpUser: Y
    dn: uid=dev-ftp,ou=ftpusers,ou=applications,o=regg.com
    dn: uid=case_201,ou=ftpusers,ou=applications,o=regg.com
    AccessFTPexpire: 05/03/2017
    ftpUser: Y
    

    基于我的理解,我尝试了如下方法,但这只是打印所有内容。

    $ ftp_pasr.py 
    prefix = ['dn', 'AccessFTPexpire', 'ftpUser']
    fh = open("ftpdata")
    for line in fh:
        line = line.strip()
        if line.startswith(tuple(prefix)):
            print(line)
    

    基于专家贡献和我的建议的答案 总结了以下两个代码 Noob &安培 gboffi 因为它们符合要求:

    1)基于Re-Pattern Suggest,我曾经从文件中读取数据并转换 List tuple 输出到字符串中,每一个都将输出分离成一个换行符,因此它可能变得更可读。

    #!/usr/bin/python3
    import re
    #with open('ftpacc3', 'r') as f:
    with open('ftpdata', 'r') as f:
        for line in f:
            data = f.read()
            #data = f.read().replace('\n', '')
            regex = (r"dn:(.*?)\ncdsAccessFTPexpire: (\d{2}\/\d{2}\/\d{4})\nftpUser: (.*)")
            matchObj = re.findall(regex, data)
            for index in matchObj:
                index_str = ' '.join(index)
                print(index_str)
    

    结果输出…

    $ ./ftp_parse.py
       uid=case_101,ou=ftpusers,ou=applications,o=regg.com 05/03/2017 T
       uid=case_201,ou=ftpusers,ou=applications,o=regg.com 05/03/2017 Y
    

    2)另一个很好的方法是 GBOFI公司 ,我再次使用了基于文件的方法 end='\n' 在每个结果输出之间留出空间。

    $/usr/bin/python
    $ ftp_parse.py
    import re
    buffer = [[], [], []]
    a, b, c = 0, 1, 2
    
    f = open("ftpdata")
    for n, line in enumerate(f):
        buffer[n%3] = line
        a, b, c = b, c, a
        if (n>1 and
                buffer[a].startswith('dn') and
                buffer[b].startswith('cdsAccessFTPexpire') and
                buffer[c].startswith('ftpUser')) :
            print(buffer[a], buffer[b], buffer[c], sep='', end='\n')
    

    结果输出….

    $ ./ftp_parse.py
    dn: uid=case_101,ou=ftpusers,ou=applications,o=regg.com
    AccessFTPexpire: 05/03/2017
    ftpUser: T
    
    dn: uid=case_201,ou=ftpusers,ou=applications,o=regg.com
    AccessFTPexpire: 05/03/2017
    ftpUser: Y
    
    2 回复  |  直到 6 年前
        1
  •  1
  •   gboffi    6 年前

    我把这个答案写在形合里,你只想打印一组 行,第一行以 'dn' ,第二个 'AccessFTPexpire' 第三个以 'ftpUser

    首先,让我们准备使用您的数据

    In [76]: from io import StringIO
    
    In [77]: data = '''dn: uid=dev-ftp,ou=ftpusers,ou=applications,o=regg.com
        ...: dn: uid=dev-ftp,ou=ftpusers,ou=applications,o=regg.com
        ...: dn: uid=case_101,ou=ftpusers,ou=applications,o=regg.com
        ...: AccessFTPexpire: 05/03/2017
        ...: ftpUser: T
        ...: dn: uid=test-ftp,ou=ftpusers,ou=applications,o=regg.com
        ...: ftpUser: Y
        ...: dn: uid=dev-ftp,ou=ftpusers,ou=applications,o=regg.com
        ...: dn: uid=case_201,ou=ftpusers,ou=applications,o=regg.com
        ...: AccessFTPexpire: 05/03/2017
        ...: ftpUser: Y
        ...: '''
    
    In [78]: f = StringIO(data)
    

    接下来,我将使用3个插槽 buffer 保存读取的最后一行和变量 a 我是说, b c 要保持对插槽中行顺序的引用,请使用 总是指向最早的一行 C类 总是指向最新的

    In [79]: buffer = [[], [], []]
    
    In [80]: a, b, c = 0, 1, 2
    

    我们对文件行数和循环,
    我们把当前的线路 缓冲器 ,就位 n%3 我是说,
    我们(通过滚动)更新 a, b, c ,
    如果 n>1 这个 缓冲器 满了,我们检查三个条件
    并可能打印缓冲区的内容。

    In [81]: for n, line in enumerate(f):
        ...:     buffer[n%3] = line
        ...:     a, b, c = b, c, a
        ...:     if (n>1 and
        ...:         buffer[a].startswith('dn') and
        ...:         buffer[b].startswith('AccessFTPexpire') and
        ...:         buffer[c].startswith('ftpUser')) :
        ...:         print(buffer[a], buffer[b], buffer[c], sep='', end='')
    dn: uid=case_101,ou=ftpusers,ou=applications,o=regg.com
    AccessFTPexpire: 05/03/2017
    ftpUser: T
    dn: uid=case_201,ou=ftpusers,ou=applications,o=regg.com
    AccessFTPexpire: 05/03/2017
    ftpUser: Y
    
        2
  •  2
  •   chirag    6 年前

    你可以用正则表达式。

    我为你的案子做了一个 regex101

    希望这有帮助。

    组1为您获取uid行。

    第二组给你日期。

    第三组给你Y或T。

    import re
    
    string = "dn: uid=dev-ftp,ou=ftpusers,ou=applications,o=regg.com\ndn: uid=dev-ftp,ou=ftpusers,ou=applications,o=regg.com\ndn: uid=case_101,ou=ftpusers,ou=applications,o=regg.com\nAccessFTPexpire: 05/03/2017\nftpUser: T\ndn: uid=test-ftp,ou=ftpusers,ou=applications,o=regg.com\nftpUser: Y\ndn: uid=dev-ftp,ou=ftpusers,ou=applications,o=regg.com\ndn: uid=case_201,ou=ftpusers,ou=applications,o=regg.com\nAccessFTPexpire: 05/03/2017\nftpUser: Y"
    
    regex = (r"dn:(.*?)\nAccessFTPexpire: (\d{2}\/\d{2}\/\d{4})\nftpUser: (.*)")
    
    matchObj = re.findall(regex,string)
    
    print(matchObj)
    

    这将获得以下输出:

    [(' uid=case_101,ou=ftpusers,ou=applications,o=regg.com', '05/03/2017', 'T'), (' uid=case_201,ou=ftpusers,ou=applications,o=regg.com', '05/03/2017', 'Y')]