首页 > 解决方案 > Python 搜索以模式 dn 开头的行并使用 oteh 子模式打印接下来的 2 行

问题描述

我有一个包含一些数据的原始文件,但是我只想要一些相关数据,如果行^dn以子模式之后的模式开头AccessFTPexpireftpUser然后打印这些行并跳过/忽略其他行,我想要。

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

$ 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)基于重新模式建议,我曾经从文件中读取数据并将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)现在,我提出了另一种出色的方法gboffi,我再次将其与基于文件的方法一起使用,只是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

标签: python-3.x

解决方案


You can use Regex.

I've made one for your case on regex101

Hope this helps.

Group 1 gets you the uid line.

group 2 gets you the date.

group 3 gets you Y or 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)

This will get you the following output:

[(' 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')]

推荐阅读