【问题标题】:Remove all lines between the pattern删除图案之间的所有线条
【发布时间】:2014-12-19 00:47:40
【问题描述】:

我想从文本中提取:

CHEXA*          99001088        99001001        99001143        99001179*00072A1
*00072A1        99001047        99001104        99001144        99001180*00072A2
*00072A2        99001048        99001105                                
RBE3*           99001089                        99001001             123*00072A5
*00072A50.11263443595303             123         6001515.041507658257159*00072A6
*00072A6         60016620.61808377914687             123         6001542
CHEXA*          99001086        99001001        99001128        99001095*0007299
*0007299        99001081        99001171                                *000729B
*000729B

这部分:

RBE3*           99001089                        99001001             123*00072A5
*00072A50.11263443595303             123         6001515.041507658257159*00072A6
*00072A6         60016620.61808377914687             123         6001542

把它放在一个文件中,然后从初始文件中删除,之后会是这样:

CHEXA*          99001088        99001001        99001143        99001179*00072A1
*00072A1        99001047        99001104        99001144        99001180*00072A2
*00072A2        99001048        99001105                                
CHEXA*          99001086        99001001        99001128        99001095*0007299
*0007299        99001081        99001171                                *000729B
*000729B

我尝试的是:

sed '/RBE3\*/,/\*/d'

但不幸的是,它会在第一次出现 后停止。但目的是在满足RBE3后删除所有行,以*开头,这一行只会删除一行。谢谢你

【问题讨论】:

    标签: python awk sed


    【解决方案1】:
    import os
    
    keep = True
    with open(pathToInput) as infile, open(pathToOutput, 'w') as outfile, open(pathToSave) as savefile:
        for line in infile:
            if line.startswith("RBE3"):
                keep = False
            elif not line.startswith("*"):
                keep = True
            if keep:
                outfile.write(line)
            else:
                savefile.write(line)
    
    os.remove(pathToInput)
    os.rename(pathToOutput, pathToInput)
    

    【讨论】:

    • 这可以很好地删除行。您是否还可以添加一部分以将已删除的行保存在新文件中。谢谢
    • 很容易弄清楚如何编写删除的行:open(in_file) 作为 infile,open(out_file, 'w') 作为 outfile,open(out_rbe3, 'w') 作为 outfile1 : ` for line in infile:` ` if line.startswith("RBE3"):` ` keep = False` ` elif not line.startswith("*"):` ` keep = True` ` if keep:` ` outfile .write(line)` ` else: ` ` outfile1.write(line)`
    • @Drago:我已经编辑了我的帖子,以便您能够保存 RBE3 数据
    【解决方案2】:
    RBE3\*[^\n]*\n(?:\*[^\n]*\n)*
    

    试试这个。替换为empty string。查看演示。

    https://regex101.com/r/vN3sH3/3

    print re.sub(r"RBE3\*[^\n]*\n(?:\*[^\n]*\n)*","",text)
    

    【讨论】:

      【解决方案3】:

      通过python的re模块。

      import re
      with open('/path/to/the/infile') as infile, open('/path/to/the/outfile', 'w+') as out:
          foo = infile.read()
          out.write(re.sub(r'(?s)RBE3\*.*?\n(?!\*)', r'', foo))
      

      更新:

      import re
      with open('/path/to/the/infile') as infile, open('/path/to/the/outfile', 'w+') as out, open('/path/to/the/file/to/save/deleted/lines', 'w+') as save:
          foo = infile.read()
          out.write(re.sub(r'(?s)(.*?\n)(RBE3\*.*?\n(?!\*))(.*)', r'\1\3', foo))
          save.write(re.sub(r'(?s)(.*?\n)(RBE3\*.*?\n(?!\*))(.*)', r'\2', foo))
      

      【讨论】:

      • 你好@Avinash Raj。删除模式之间的线条效果很好。但是您能否解释一下并添加部分以将已删除的行保存在单独的文件中。谢谢
      • 不幸的是,我收到错误 RuntimeError: 'internal error in regular expression engine' 请检查一下。谢谢
      • 它对我有用。你能发布确切的错误报告吗?
      • (Pdb) next RuntimeError: 'internal error in regular expression engine' > c:\users\ddc\documents\python_scripts\delete_patterns.py(15)() -> out.write (re.sub(r'(?s)(.*?\n)(RBE3*.*?\n(?!*))(.*)', r'\1\3', foo)) ( pdb)
      • 我在 Python 2.7 中使用 Spyder
      【解决方案4】:

      使用 awk:

      awk -v flag=0 '
          /^[^\*]/  { flag = 0 } # clear flag if the line does not start with a *
          /^RBE3\*/ { flag = 1 } # except if it is the starting line of an ignored block
          flag == 0 { print }    # print if ignore flag is not set.
        ' foo.txt
      

      这样做的好处是它很容易扩展为反转。如果你写

      awk -v flag=0 -v ignore=0 '
          /^[^\*]/ { flag = 0 }
          /^RBE3\*/ { flag = 1 }
          flag != ignore { print }
        ' foo.txt
      

      然后通过将ignore=0 替换为ignore=1,您可以提取块而不是忽略它。

      【讨论】:

        【解决方案5】:

        使用 awk:

        awk '{if(match($0,"RBE3")>0)flag=0}{if(match($0,"CHEXA")>0)flag=1}{if(flag==1) print $0}' File
        

        输出:

        CHEXA*          99001088        99001001        99001143        99001179*00072A1
        *00072A1        99001047        99001104        99001144        99001180*00072A2
        *00072A2        99001048        99001105                                
        CHEXA*          99001086        99001001        99001128        99001095*0007299
        *0007299        99001081        99001171                                *000729B
        *000729B
        

        【讨论】:

          【解决方案6】:

          这是一个适用于 Python 或 PCRE 的正则表达式

          /(RBE3\*).+(?=CHEXA\*)/s(注意s 修饰符是它工作所必需的。)

          一个简单的python实现:

          import re
          import os
          inPut = "list"
          outPut = "tmp"
          
          regexp = re.compile("(RBE3\*).+(?=CHEXA\*)", re.S)
          
          with open(inPut, 'r') as f:
              fileStr = f.read()
          match = regexp.search(fileStr).group(0)
          ret = re.sub(regexp, "", fileStr)
          with open(outPut, 'w') as tmpFile:
              tmpFile.write(match)
          os.remove(inPut)
          os.rename(outPut, inPut)
          

          【讨论】:

            【解决方案7】:
            awk -v key="RBE3" '
            index($0,key"*")==1 { f=1; print > "newfile" }
            f && /^\*/ { print > "newfile"; next }
            { f=0; print }
            ' file > tmp && mv tmp file
            

            上面使用 index() 所以它是在做一个字符串而不是正则表达式比较,所以如果你的键包含 RE 元字符它不会失败,这与任何 sed 解决方案不同。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2015-10-28
              • 2018-07-12
              • 2014-01-06
              • 2018-12-26
              • 2010-11-28
              • 1970-01-01
              • 2018-01-16
              相关资源
              最近更新 更多