Python搜索以模式dn开头的行,并用oteh子模式打印接下来的2行

时间:2018-06-26 07:44:23

标签: python-3.x

我有一个包含一些数据的原始文件,但是我只想要一些相关的数据,我想如果行以子模式^dnAccessFTPexpire之后的模式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)
  

基于我的专家贡献和建议的答案   总结了Noobgboffi选择并借用的以下两个鳕鱼,因为它们符合要求:

1)根据re模式的建议,我曾经从文件中读取数据并将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

2 个答案:

答案 0 :(得分:2)

您可以使用正则表达式。

我为您的案件在this page上做了

希望这会有所帮助。

第1组让您获得uid行。

第2组为您获取日期。

第3组让您获得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')]

答案 1 :(得分:1)

我在假设中写这个答案,即您只想打印 行的组,第一行以'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来保存最后读取的行,并使用变量abc来保留对插槽中各行的顺序,a始终指向最旧的行,c始终指向最新的行

In [79]: buffer = [[], [], []]

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

我们对文件的行进行计数和循环,
我们将当前行放在buffer的{​​{1}}中,
我们(通过滚动)更新n%3
如果a, b, c的{​​{1}}已满,我们将检查三个条件
并可能打印缓冲区的内容。

n>1