除了特定的文本块,如何将行写入新文件?

时间:2019-07-15 21:08:59

标签: python

我正在打开一个文本文件,搜索以查找特定的行(将以前的行写入新文件)。找到该行(“ BASE CASE”)后,我要搜索特定的文本块以将其从文件中删除。

我通过在线研究类似问题构建了一些代码。现在,它仅创建一个空的新eve文件。当我尝试删除空白文件时,这也给我一个错误:“此文件正在python中使用”。旧文件的示例如下:每个块可能有未知数量的监视器。

xxxoijasdf
Monitor 4
aowijefoi
BASE CASE

Monitor 5
Monitor 3
Monitor 2
Item 1 Item 2
End

Monitor 3
Monitor 4
Item 3 Item 4
End

Monitor 1
Item 5 Item 6
End

我当前拥有的代码是:

    longStr1 = (r"C:\Users\jrwaller\Documents\Automated Eve\NewTest.txt")
    endfile1 = (r"C:\Users\jrwaller\Documents\Automated Eve\did we do it yet.txt")

    search_item = "Item 3 Item 4"

    with open(longStr1, "r") as f:
        with open(endfile1, "w") as new_file:
            lines = f.readlines()
            i=0
            while i < 2000:
                for line in f:
                    if lines[i] != 'BASE CASE':
                        new_file.write(lines[i])
                    else:
                        new_file.write(lines[i])
                        newfile.write(lines[i+1])
                        block = ''
                        for line in f:
                            if block:
                                block += line
                                if line.strip() == 'End':
                                    if search_item not in block: new_file.write(block + '\n')
                                    block = ''
                            elif line.startswith('Monitor'):
                                block = line
        new_file.close()
    f.close()

我希望在删除第一个“ End”和“ Monitor 1”之间的文本块时,将旧的txt文件重新打印为新文件。当前的问题包括输出文件为空白,而输出文件在python中保持打开状态。

2 个答案:

答案 0 :(得分:1)

您正在描述一个简单的状态机。您的状态是:

  1. 初始状态-将行写入新文件
  2. 找到“ BASE CASE”-将行写入新文件
  3. 找到“结束”-不执行任何操作
  4. 此行是“监视器1”-将行写入新文件
  5. 后来,到EOF -将行写入新文件

由于只有两个动作(“写”和“不写”),您可以使用状态变量和一个动作标志来处理。像这样:

state = 1
write_out = True
for line in f:
    # Looking for "BASE CASE"; write line until then
    if state == 1:
        if "BASE CASE" in line:
            state = 2

    # Look for start of unwanted block
    elif state == 2:
        if "End" in line:
            state = 3
            write_out = False

    # Look for end of unwanted block
        ...

    # Acknowledge moving past "Monitor 1"
        ...

    # Iterate through rest of file
        ...

    if write_out:
        new_file.write(line)

如果愿意,可以将其编写为一系列隐式状态循环:

while not "BASE CASE" in line:
    new_file.write(line)
    line = f.readline()

while not "End" in line:
    new_file.write(line)
    line = f.readline()

while not "Monitor 1" in line:
    # Don't write this block to the output
    line = f.readline()

...

你能从那里拿走吗?

答案 1 :(得分:1)

longStr1 = (r"C:\Users\jrwaller\Documents\Automated Eve\NewTest.txt")
endfile1 = (r"C:\Users\jrwaller\Documents\Automated Eve\did we do it yet.txt")

search_item = "Item 3 Item 4"

with open(longStr1, "r") as f:
    with open(endfile1, "w+") as new_file:
        state = 1
        write_out = True
        for line in f:
            if state == 1:
                write_out = True
                if "BASE CASE" in line:
                    state = 2
            elif state == 2:
                if line == '\n':
                    write_out = True
                    state = 3
            elif state == 3:
                write_out = True
                block = ''
                for line in f:
                    if block:
                        block += line
                        if line.strip() == 'End':
                            if search_item not in block: new_file.write(block + '\n')
                            block = ''
                    elif line.startswith('Monitor'):
                        block = line
                if search_item in line:
                    state = 4 
                    write_out = False
            elif state == 4:
                write_out = False
                if "End" in line:
                    state = 5    
                    write_out = False
            elif state == 5:              
                if "Monitor" in line:
                    write_out = True
                    state = 6                  
            elif state == 6:
                write_out = True
            if write_out:
                new_file.write(line)
f.close()
new_file.close()