尝试根据关键字从文件中删除特定行

时间:2013-12-06 19:05:47

标签: python file lines

我有一个非常具体的问题。我试图根据关键字find删除服务器配置文件中的某些行。如果您向下滚动底部的代码,我试图删除目录行中具有关键字“nasdaq”的代码块。这包括从“数据库”一直到底部的所有内容,其中包含“index termName pres,eq”。

我能解决这个问题的最佳方式是什么? String.find()?我应该使用哪些命令来删除关键字行上方和下方的行?

此外,我可以删除行或只是写入新文件并忽略最后一个块。需要一些指导!

include         /home/tuatara/TuataraServer-2.0/etc/openldap/schema/core.schema
include         /home/tuatara/TuataraServer-2.0/etc/openldap/schema/cosine.schema
include         /home/tuatara/TuataraServer-2.0/etc/openldap/schema/inetorgperson.schema
include         /home/tuatara/TuataraServer-2.0/etc/openldap/schema/tuatara.schema
pidfile         /home/tuatara/TuataraServer-2.0/var/slapd.pid
argsfile        /home/tuatara/TuataraServer-2.0/var/slapd.args

database        ldbm
loglevel        0
directory       /home/tuatara/TuataraServer/var/openldap-ldbm-CMDB-spellchecker-20130106-06_20_31_PM
suffix          "o=CMDB-spellchecker"
suffix          "dc=CMDB-spellchecker,dc=com"
rootdn          "cn=admin,o=CMDB-spellchecker"
rootpw          tuatara
schemacheck     on
lastmod         off
sizelimit       100000
defaultaccess   read
dbnolocking
dbnosync
cachesize       100000
dbcachesize     1000000
dbcacheNoWsync
index           objectclass pres,eq
index           default pres,eq
index           termName pres,eq

database        ldbm
loglevel        0
directory       /home/tuatara/TuataraServer/var/openldap-ldbm-CMDB-spellchecker.medicinenet-20130106-06_20_31_PM
suffix          "o=CMDB-spellchecker.medicinenet"
suffix          "dc=CMDB-spellchecker.medicinenet,dc=com"
rootdn          "cn=admin,o=CMDB-spellchecker.medicinenet"
rootpw          tuatara
schemacheck     on
lastmod         off
sizelimit       100000
defaultaccess   read
dbnolocking
dbnosync
cachesize       100000
dbcachesize     1000000
dbcacheNoWsync
index           objectclass pres,eq
index           default pres,eq
index           termName pres,eq

database        ldbm
loglevel        0
directory       /home/tuatara/TuataraServer/var/openldap-ldbm-CMDB-nasdaq-20131127-12_37_43_PM
suffix          "o=CMDB-nasdaq"
suffix          "dc=CMDB-nasdaq,dc=com"
rootdn          "cn=admin,o=CMDB-nasdaq"
rootpw          tuatara
schemacheck     on
lastmod         off
sizelimit       100000
defaultaccess   read
dbnolocking
dbnosync
cachesize       100000
dbcachesize     100000000
dbcacheNoWsync
index           objectclass pres,eq
index           default pres,eq
index           termName pres,eq

3 个答案:

答案 0 :(得分:3)

正如已经提到的,sed是为这种东西而构建的,但你可以在python中用这样的东西来做:

with open('nasdaq.txt') as fin, open('nonasdaq.txt', 'w') as fout:
    for line in fin:
        if 'nasdaq' not in line:
            fout.write(line)

它只是循环输入文件的行,如果它们不包含字符串'nasdaq',则将它们复制到输出文件。

答案 1 :(得分:2)

这应该符合您的需要,我想:

import re

pat = '(?:^(?![\t ]*\r?\n).+\n)*?'\
      '.*nasdaq.*\n'\
      '(?:^(?![\t ]*\r?\n).+\n?)*'

filename = 'to_define.txt'

with open(filename,'rb+') as f:
    content = f.read()
    f.seek(0,0)
    f.write(re.sub(pat,'',content,flags=re.M))


    f.truncate()

仅当部分真的与空行分隔时才有效(它可能是一行'\ n'或一行'\ t \ n',带有空格和制表符,无关紧要)

'(?:^(?![ \t]*\r?\n).+\n)*?'\
'.*nasdaq.*\n'\
'(?:^(?![ \t]*\r?\n).+\n?)*'

[\t ]表示可以是制表符或空白的字符 [\t ]*表示一个字符,可以是制表符或空格,重复0次或更多次
(?!开始出现负面的先行断言 (?=开始积极的先行断言 (?![\t ]*\r?\n)表示此位置后不得有以下序列:连续零个或多个'空格或制表符',字符\ r \ n(可能不存在)和字符换行符\ n
当我使用“位置”一词时,它表示两个字符之间的位置 断言意味着从它所处的位置开始的东西 在上面的RE中,负向前瞻断言放在符号^之后,这意味着位于行的第一个字符之前。
因此,上面的断言,就像它所放置的那样,意味着:从位于一行开头的位置,一定不能有一个序列0 or more tab/blank-potential \r-\n
请注意,只有在激活标记^时,符号re.MULTILINE才意味着“”的开头。

现在部分RE (?! *\r?\n)位于以下RE内:
(?:^.+\n)*?
通常,(...)定义一个捕获组 在parens之间放置?:的结果是这些parens不再定义捕获组。但是(?:......)对于定义RE非常有用。

此处.+\n表示一系列任何字符(\n除外),然后是\n

并且^.+\n(已激活标记re.M)表示从一行开头的,除了换行符和换行符之外的任何字符的继承
请注意,由于点 . 与除\n之外的任何字符匹配,我们确信.+无法与超出结尾的序列匹配由\n发出信号的线 然后^.+\n实际定义了一条线!

现在我们有什么?
取消捕获组之后有一个*。这意味着匹配(?:^.+\n)的子字符串重复0次或更多次:也就是说我们匹配一连串的行。

但不是任何一条线,因为存在负面的先行断言,你现在知道它的含义。
因此,RE (?:^(?![\t ]*\r?\n).+\n)*匹配的是:一连串的行,其中没有空行。空行是\n`\t\t\n\t \t \n等(我不能代表只有空格的行,在srackoverflow上,但它也是空行)

此RE末尾的问号意味着一旦接下来的RE,一个接一个地匹配这些非空行的正则表达式电机的进程必须立即停止。
以下RE是.*nasdaq.*\n,这意味着一行中有'nasdaq'

还有一些细微之处,但我会在这里停下来 我认为其余部分对你来说也更容易理解。

修改

如果一个部分是最后一个部分,并且其最后一行将包含nasdaq,则上述正则表达式不会捕获和删除它。
要更正此问题,必须将.*nasdaq.*\n部分替换为.*nasdaq.*(\n|\Z),其中\Z表示字符串的最后一部分。

我还在正则表达式中添加了一个部分,以便在每个部分之后捕获空行,因此清除了这些行的文件。

pat = '(?:^(?![\t ]*\r?\n).+\n)*?'\
      '.*?nasdaq.*(\n|\Z)'\
      '(?:^(?![\t ]*\r?\n).+\n?)*'\
      '(?:[\t ]*\r?\n)*'

答案 2 :(得分:1)

with open('nasdaq.txt','r') as f:
    text = [l for l in f.read().splitlines()]

text = text[9:] # get rid of include headers
n = 20 # yours chunks are about this size

# sort chunks into list of lists
groups = []
for i in range(0, len(text), n):
    chunk = text[i:i+n]
    groups.append(chunk)

# get rid of unwanted lists by keyword
for ind,g in enumerate(groups):
    if any('nasdaq' in x for x in g):
        toss = groups.pop(ind)