首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尝试根据关键字从文件中删除特定行

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

Stack Overflow用户
提问于 2013-12-06 19:05:46
回答 3查看 1.1K关注 0票数 0

我有个很特别的问题。我试图根据关键字查找从服务器配置文件中删除某些行。如果你向下滚动下面的代码在底部,我试图删除的代码块,其中关键字“纳斯达克”目录行。这包括从“数据库”行一直到底部的所有内容,其中读取"index termName pres,eq“。

我做这件事最好的方法是什么?String.find()?我应该使用哪些命令来删除关键字行上方和下面的行?

另外,我可以删除这些行,或者直接写到一个新文件中,忽略最后一个块。需要一些指导!

代码语言:javascript
复制
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
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-12-06 20:36:48

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

代码语言:javascript
复制
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‘带空格和制表符,没关系)

代码语言:javascript
复制
'(?:^(?![ \t]*\r?\n).+\n)*?'\
'.*nasdaq.*\n'\
'(?:^(?![ \t]*\r?\n).+\n?)*'

[\t ]的意思是,一个字符可以是制表符,也可以是空白的

[\t ]*的意思是字符,可以是制表符,也可以是空字符,可以重复0次或多次

(?!开始了一个负面的前瞻性断言

(?=开始了一个积极的前瞻性断言

(?![\t ]*\r?\n)的意思是,在这个位置之后不能有以下序列:连续的‘空白或制表符’、字符\r (可能没有)和字符换行符\n

当我使用“位置”这个词时,意思是两个字符之间的位置。

断言是指它所放置的位置上的某物。

在上面的RE中,负的查找断言放在符号^之后,这意味着位置在一行的第一个字符之前。

因此,上面的断言,正如它所放置的,意思是:从位于行首的位置起,就不能有序列

注意,只有当标志^被激活时,符号re.MULTILINE才意味着“的开始”。

现在,部分RE (?! *\r?\n)位于以下RE中:

(?:^.+\n)*?

通常,(...)定义一个捕获组。

在双亲之间插入?:的结果是,这些父母亲不再定义捕获组。但是(?:......)对于定义RE是有用的。

在这里,\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'

还有更多的微妙之处,但我会在这里停下来。

我想剩下的对你来说也会更容易理解。

编辑

如果某一段是最后一段,而它的最后一行将包含纳斯达克,那么它就不会被上面的regex所捕捉和删除。

要纠正这一点,必须将部件.*nasdaq.*\n替换为.*nasdaq.*(\n|\Z),其中\Z表示字符串的末尾。

我还在regex中添加了一个部分,用于在每个部分之后捕获空行,因此文件中清除了这些行。

代码语言:javascript
复制
pat = '(?:^(?![\t ]*\r?\n).+\n)*?'\
      '.*?nasdaq.*(\n|\Z)'\
      '(?:^(?![\t ]*\r?\n).+\n?)*'\
      '(?:[\t ]*\r?\n)*'
票数 2
EN

Stack Overflow用户

发布于 2013-12-06 19:18:20

如前所述,sed是为这类东西构建的,但是您可以在python中这样做:

代码语言:javascript
复制
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”,则将它们复制到输出文件中。

票数 3
EN

Stack Overflow用户

发布于 2013-12-06 19:30:26

代码语言:javascript
复制
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)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20431670

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档