【问题标题】:Remove entire line in text file that contain with specific word/string in python删除文本文件中包含python中特定单词/字符串的整行
【发布时间】:2019-05-17 08:07:13
【问题描述】:

全部。 我使用 SO 中的示例并尝试删除文本文件中的几行/字符串但不成功。例如需要删除的字符串行

             OSPF Process 1 with Router ID 1.1.1.1
                       Area: 0.0.0.11
               Link State Database  

我可以通过准确指定如下的整个字符串/行来删除这些行,但这一次只能删除一行,另一个问题是路由器 ID 和区域可以是任意数字并动态更改。

filename = 'raw.txt'
with open(filename, 'r') as fin:
    lines = fin.readlines()
with open('clean.txt', 'w') as fout:
    for line in lines:
        if 'Area: 0.0.0.10' not in line:
            fout.write(line)

我尝试使用 startwith 但它没有删除它。

if not line.startswith('OSPF'):

这就是文本文件中的外观和字符串位置。 OSPF...、Area...、Link... 行不是从左边开始的,它以空格开头,所以我认为这就是为什么 startswith 不起作用的原因。


     OSPF Process 1 with Router ID 1.1.1.1
                 Area: 0.0.0.11
         Link State Database 


some textxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

         OSPF Process 1 with Router ID 2.1.1.1
                 Area: 0.0.0.12
         Link State Database 

some textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


     OSPF Process 1 with Router ID 2.2.2.2
                 Area: 0.0.0.33
         Link State Database 

some textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

删除这些行后预期如下

some textxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


some textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx


some textxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

请多多指教,谢谢

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


     OSPF Process 1 with Router ID 1.1.1.1
                 Area: 0.0.0.11
         Link State Database 


例如上面 5 行当执行脚本时..它会删除 3 行但仍然保留 2 行

另一个例子

 * Link ID: 10.1.155.20
     Data   : 255.255.255.252
     Link Type: StubNet
     Metric : 1
     Priority : Low
                         Area: 0.0.0.13
                 Link State Database


  Type      : Router
  Ls id     : 1.4.0.2
  Adv rtr   : 1.4.0.2

这有 4 行(在区域之间和类型之前)...执行脚本时仅删除 2 行...并且将保留 2...。 为此...最终应该如下所示

* Link ID: 10.1.155.20
     Data   : 255.255.255.252
     Link Type: StubNet
     Metric : 1
     Priority : Low

  Type      : Router
  Ls id     : 1.4.0.2
  Adv rtr   : 1.4.0.2

删除特定的字符串和行及其下一行(在链接状态数据库行之后)

clean.txt

**To remove this empty line
To remove this empty line
To remove this empty line**
  Type      : Router
  Ls id     : 1.4.0.1
  Adv rtr   : 1.4.0.1
  Ls age    : 996
  Len       : 48
  Options   :  ASBR  E
  seq#      : 8000002f
  chksum    : 0xe7f5
  Link count: 2
   * Link ID: 1.16.9.9
     Data   : 10.1.155.2
     Link Type: P-2-P
     Metric : 100
   * Link ID: 10.1.155.20
     Data   : 255.255.255.252
     Link Type: StubNet
     Metric : 100
     Priority : Low

  Type      : Router
  Ls id     : 1.16.9.9
  Adv rtr   : 1.16.9.9
  Ls age    : 392
  Len       : 48
  Options   :  ABR  E
  seq#      : 8000001e
  chksum    : 0x3116
  Link count: 2
   * Link ID: 1.4.0.1
     Data   : 10.242.177.21
     Link Type: P-2-P
     Metric : 1
   * Link ID: 10.1.155.20
     Data   : 255.255.255.252
     Link Type: StubNet
     Metric : 1
     Priority : Low
**To remove this empty line**

  Type      : Router
  Ls id     : 1.4.0.2
  Adv rtr   : 1.4.0.2
  Ls age    : 1194
  Len       : 96
  Options   :  ASBR  E
  seq#      : 8001cf7b
  chksum    : 0xbfae
  Link count: 6
   * Link ID: 1.4.0.2
     Data   : 255.255.255.255
     Link Type: StubNet
     Metric : 0
     Priority : Medium
   * Link ID: 1.4.0.1
     Data   : 10.0.0.2
     Link Type: P-2-P
     Metric : 10
   * Link ID: 10.0.0.0
     Data   : 255.255.255.252
     Link Type: StubNet
     Metric : 10
     Priority : Low
   * Link ID: 10.40.8.0
     Data   : 255.255.255.252
     Link Type: StubNet
     Metric : 100
     Priority : Low
   * Link ID: 19.23.23.15
     Data   : 10.40.10.130
     Link Type: P-2-P
     Metric : 10
   * Link ID: 1.4.10.200
     Data   : 255.255.255.252
     Link Type: StubNet
     Metric : 10
     Priority : Low
To remove this empty line

  Type      : Router
  Ls id     : 100.100.0.10
  Adv rtr   : 100.100.0.10
  Ls age    : 171
  Len       : 84
  Options   :  ASBR  E
  seq#      : 8001a292
  chksum    : 0x5fa2
  Link count: 5
   * Link ID: 100.100.0.10
     Data   : 255.255.255.255
     Link Type: StubNet
     Metric : 12
     Priority : Medium
   * Link ID: 10.10.0.1
     Data   : 10.10.10.18
     Link Type: P-2-P
     Metric : 10
   * Link ID: 10.10.10.17
     Data   : 255.255.255.255
     Link Type: StubNet
     Metric : 10
     Priority : Medium
   * Link ID: 19.23.23.15
     Data   : 10.10.30.30
     Link Type: P-2-P
     Metric : 10
   * Link ID: 10.90.25.30
     Data   : 255.255.255.255
     Link Type: StubNet
     Metric : 10
     Priority : Medium

  Type      : Router
  Ls id     : 10.10.0.1
  Adv rtr   : 10.10.0.1
  Ls age    : 191
  Len       : 96
  Options   :  ASBR  E
  seq#      : 80013bcf
  chksum    : 0x9871
  Link count: 6
   * Link ID: 10.10.0.1
     Data   : 255.255.255.255
     Link Type: StubNet
     Metric : 12
     Priority : Medium
   * Link ID: 15.51.51.14
     Data   : 10.10.0.130
     Link Type: P-2-P
     Metric : 10
   * Link ID: 10.10.0.129
     Data   : 255.255.255.255
     Link Type: StubNet
     Metric : 10
     Priority : Medium
   * Link ID: 100.100.0.10
     Data   : 10.10.10.17
     Link Type: P-2-P
     Metric : 10
   * Link ID: 10.10.10.18
     Data   : 255.255.255.255
     Link Type: StubNet
     Metric : 10
     Priority : Medium
   * Link ID: 16.16.16.0
     Data   : 255.255.255.252
     Link Type: StubNet
     Metric : 10
     Priority : Low

  Type      : Router
  Ls id     : 15.51.51.14
  Adv rtr   : 15.51.51.14
  Ls age    : 2487
  Len       : 60
  Options   :  ASBR  ABR  E
  seq#      : 8000003c
  chksum    : 0x1714
  Link count: 3
   * Link ID: 10.242.95.12
     Data   : 255.255.255.252
     Link Type: StubNet
     Metric : 1
     Priority : Low
   * Link ID: 10.10.0.1
     Data   : 10.10.0.129
     Link Type: P-2-P
     Metric : 1
   * Link ID: 10.10.0.128
     Data   : 255.255.255.252
     Link Type: StubNet
     Metric : 1
     Priority : Low
**To remove this empty line
To remove this empty line**

【问题讨论】:

  • 所以你想要保留的所有行都有一个非空白字符作为行中的第一个字符?
  • @AndrewAllen 不是真的先生......我需要保留的一些行也有空格,但不像我要删除的行

标签: python string split extract


【解决方案1】:

请注意,该行不是OSPF开头,而是以一堆空格和然后 OSPF。首先尝试strip。此外,startswith 可以采用一组可能的前缀,因此您可以一次性检查所有内容。

for line in lines:
    if not line.strip().startswith(("OSPF", "Area", "Link State")):
        fout.write(line)

请注意,如果实际文本中的某些行也以 Area 或类似名称开头,这可能会失败。

您还可以使用正则表达式来确保行 以一些空格开头,并且 然后 这些关键字之一:

import re
for line in lines:
    if not re.match(r"\s+(Area|OSPF|Link State)", line):
        fout.write(line)

【讨论】:

  • 我需要小心...这样它只会删除特定的行...另一件事是哪一个是有效的先生...开始或重新...谢谢
  • @chenoi 我认为这里的效率不是问题。您可以将正则表达式扩展到例如还以抽象的方式包含“Area”的值,那么它肯定只会匹配那些行。
  • 您好先生..我已经测试过并且它可以工作...但是当我将 clean.txt 与另一个脚本一起使用时它运行正常,但不知何故我也得到了空值...对于这个解决方案它有效。谢谢楼主
  • 由于空行而发生这种情况...需要删除 (1) 顶部空行 (2) 底部空行和 (3) 将任何 2 个空行删除为仅 1 个
  • 嗨,先生....当删除这些行时,它也会创建新的单行。执行上面的脚本时是否可以不创建该新行?谢谢
【解决方案2】:

您可以使用正则表达式来查找某些特定文本并将其删除。以下是示例代码,您可以根据需要使用不同的正则表达式。

试试下面的代码:

import re
regex = "OSPF|Area|Link"
for line in lines:
    if not re.findall(regex, line):
        print line

【讨论】:

    【解决方案3】:

    您可能会做的不是逐行阅读,而是阅读文本文件的全部内容,并为该特定匹配使用一种模式,同时考虑可能变化的数字部分。

    ^[ \t]*OSPF Process \d+ with Router ID \d+(?:\.\d+){3}\s*Area: \d+(?:\.\d+){3}\s*Link State Database\s*(?:\n|$)
    

    说明

    • ^ 字符串开始
    • [ \t]* 匹配 0+ 次空格或制表符
    • OSPF Process \d+ with Router ID \d+(?:\.\d+){3} 匹配文本,考虑到进程和路由器 ID 的数字格式 \d+
    • \s*Area: \d+(?:\.\d+){3} 匹配 Area: 后跟 1+ 位数字并重复 3 次一个点和 1+ 位数字
    • \s*Link State Database 匹配 0+ 次空格字符和文字文本
    • \s*(?:\n|$) 匹配 0+ 次空白字符,然后匹配换行符或断言字符串的结尾

    Regex demo | Python demo

    例如:

    import re
    
    filename = 'raw.txt'
    pattern = r"^[ \t]*OSPF Process \d+ with Router ID \d+(?:\.\d+){3}\s*Area: \d+(?:\.\d+){3}\s*Link State Database\s*(?:\n|$)"
    with open(filename, 'r') as fin:
        res = re.sub(pattern, "", fin.read(), 0, re.MULTILINE)
        text_file = open("clean.txt", "w")
        text_file.write(res)
        text_file.close()
    

    编辑

    要匹配一个空的换行符,你可以在数据库之后使用添加:

    • [ \t]* 匹配 0+ 次空格或字符串
    • (?:非捕获组
      • (?:\r?\n|\r)[ \t]* 匹配换行符,然后匹配 0+ 次制表符或空格
    • )?关闭非捕获组并使其可选
    • $断言字符串结束

    完整模式:

    ^[ \t]*OSPF Process \d+ with Router ID \d+(?:\.\d+){3}\s*Area: \d+(?:\.\d+){3}\s*Link State Database[ \t]*(?:(?:\r?\n|\r)[ \t]*)?$
    

    Regex demo

    【讨论】:

    • 您好先生...这项工作...但是当我将 clean.txt 传递给另一个脚本读取时出现错误(以提取特定的字符串和行).. 但是对于删除空格和特定字符串的目的......它确实有效。谢谢
    • @chenoi 欢迎您。如果任何给定的答案解决了您的问题,您可以考虑通过单击其左侧的 ✓ 和您认为有帮助的 upvote the answersaccept an answer
    • 您好先生,它确实根据需要删除..我如何将其扩展为也删除/删除它之后的行..我的意思是删除行链接状态数据库下面的行......因此。 ..删除OSPF行...区域行...链接状态行...及其下方的一行...谢谢
    • @chenoi 如果你想在匹配一个可选的空行并断言字符串结尾之后删除一行^[ \t]*OSPF Process \d+ with Router ID \d+(?:\.\d+){3}\s*Area: \d+(?:\.\d+){3}\s*Link State Database[ \t]*(?:(?:\r?\n|\r)[ \t]*)?$demo
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-03
    • 2022-07-05
    • 1970-01-01
    • 2018-06-28
    • 1970-01-01
    相关资源
    最近更新 更多