Python从文件中删除行块

Python从文件中删除行块,python,file-handling,Python,File Handling,我正在努力弄清楚应该如何从文件中删除一段行。下面是代码 #!/usr/bin/python import argparse import re import string ##getting user inputs p = argparse.ArgumentParser() p.add_argument("input", help="input the data in format ip:port:name", nargs='*') args = p.parse_args() kkk_li

我正在努力弄清楚应该如何从文件中删除一段行。下面是代码

#!/usr/bin/python
import argparse
import re
import string

##getting user inputs
p = argparse.ArgumentParser()
p.add_argument("input", help="input the data in format ip:port:name", nargs='*')  
args = p.parse_args()
kkk_list = args.input


def printInFormat(ip, port, name):
    formattedText = '''HOST Address:{ip}:PORT:{port} 
                        mode tcp 
                        bind {ip}:{port} name {name}'''.format(ip=ip, 
                                                                port=port, 
                                                                name=name)
    textWithoutExtraWhitespaces =  '\n'.join([line.strip() for line in formattedText.splitlines()])
    # you can break above thing
    # text = ""
    # for line in formattedText.splitlines():
    #       text += line.strip()
    #       text += "\n" 

    return(formattedText)

#####here im writing writing the user inoput to a file and it works great.
#with open("file.txt", "a") as myfile:
#    for kkk in kkk_list:
#         ip, port, name = re.split(":|,", kkk)
#         myfile.write(printInFormat(ip, port, name))

###### here is where im struggling. 
for kkk in kkk_list:
    ip, port, name = re.split(":|,", kkk)
    tobedel = printInFormat(ip, port, name)  
    f = open("file.txt", "r+")
    d = f.readlines()
    f.seek(0)
    if kkk != "tobedel":
        f.write(YY)
f.truncate()
f.close()
如您所见,我在file.txt中添加了用户输入。i、 e(格式:ip:端口:名称)。当脚本作为./script.py 192.168.0.10:80:string 192.168.0.10:80:string执行时,文件将包含以下条目

Host Address:192.168.0.10:PORT:80
mode tcp
bind 192.168.0.10:80 abc    
Host Address:10.1.1.10:PORT:443
mode tcp
bind 10.1.1.10:443 xyz

现在,我想在以相同的方式提供用户输入时删除file.txt中的行。运行上述代码时,不会发生任何事情。我是个初学者,如果你能帮我理解,我真的很感激。这个问题与

有多种方法。我试图创建一个新文件,留下所有的块。您可以删除旧文件并将新文件重命名为旧文件。 以下是相同的工作代码

 #!/usr/bin/python
 import argparse
 import re
 import string

##getting user inputs
p = argparse.ArgumentParser()
p.add_argument("input", help="input the data in format ip:port:name", nargs='*')  
args = p.parse_args()
kkk_list = args.input # ['192.168.1.10:80:name1', '172.25.16.2:100:name3']



# returns the next block from the available file. Every block contains 3 lines as per definition.
def getNextBlock(lines, blockIndex):
    if len(lines) >= ((blockIndex+1)*3):
        line = lines[blockIndex*3]
        line += lines[blockIndex*3+1]
        line += lines[blockIndex*3+2]
    else:
        line = ''

    return line

# file  - holds reference to existing file of all blocks. For efficiency keep the entire content in memory (lines variable)
file = open("file.txt", "r")
lines = file.readlines()
linesCount = len(lines)

# newFile holds reference to newly created file and it will have the resultant blocks after filtering
newFile = open("file_temp.txt","w")


# loop through all inputs and create a dictionary of all blocks to delete. This is done to have efficiency while removing the blocks with O(n) time

delDict = {}
for kkk in kkk_list:
    ip, port, name = re.split(":|,", kkk)
    tobedel = printInFormat(ip, port, name)
    delDict[tobedel] = 1

for i in range(linesCount / 3):
    block = getNextBlock(lines, i)
    if block in delDict:
        print 'Deleting ... '+block
    else:
        #write into new file
        newFile.write(block)

file.close()
newFile.close()

#You can drop the old file and rename the new file as old file

希望有帮助

让我指出你缺少的一些小东西

for kkk in kkk_list:
    ip, port, name = re.split(":|,", kkk)
    tobedel = printInFormat(ip, port, name)  
    f = open("file.txt", "r+")
    d = f.readlines()
    f.seek(0)
    if kkk != "tobedel":
        f.write(YY)
f.truncate()
f.close()
  • 您在循环内部打开了文件,在外部关闭了文件。文件对象超出范围。将
    一起使用,它会自动为您处理上下文

  • 在循环中打开一个文件是一个坏主意,因为它将创建太多的文件描述符,这将消耗大量资源

  • 你在写作的时候从来没有提到过什么是
    YY

  • 当您试图一次性删除多行时,可以在此处删除行,因此
    d=f.readlines()
    应该是
    d=f.read()

  • 下面是更新后的代码

    #!/usr/bin/python
    import argparse
    import re
    import string
    
    p = argparse.ArgumentParser()
    p.add_argument("input", help="input the data in format ip:port:name", nargs='*')  
    args = p.parse_args()
    kkk_list = args.input # ['192.168.1.10:80:name1', '172.25.16.2:100:name3']
    
    
    def getStringInFormat(ip, port, name):
        formattedText = "HOST Address:{ip}:PORT:{port}\n"\
                        "mode tcp\n"\
                        "bind {ip}:{port} name {name}\n\n".format(ip=ip, 
                                                                    port=port, 
                                                                    name=name)
    
        return formattedText
    
    # Writing the content in the file
    # with open("file.txt", "a") as myfile:
    #    for kkk in kkk_list:
    #         ip, port, name = re.split(":|,", kkk)
    #         myfile.write(getStringInFormat(ip, port, name))
    
    
    
    with open("file.txt", "r+") as f:
        fileContent = f.read()
    
        # below two lines delete old content of file
        f.seek(0)
        f.truncate()
    
        # get the string you want to delete
        # and update the content
        for kkk in kkk_list:
            ip, port, name = re.split(":|,", kkk)
    
            # get the string which needs to be deleted from the file
            stringNeedsToBeDeleted = getStringInFormat(ip, port, name)
    
            # remove this from the file content    
            fileContent = fileContent.replace(stringNeedsToBeDeleted, "")
    
        # delete the old content and write back with updated one
        # f.truncate(0)
        f.write(fileContent)
    
    # Before running the script file.txt contains 
    
    # HOST Address:192.168.1.10:PORT:80
    # mode tcp
    # bind 192.168.1.10:80 name name1
    #
    # HOST Address:172.25.16.2:PORT:100
    # mode tcp
    # bind 172.25.16.2:100 name name3
    
    # After running file.txt will be empty
    # as we have deleted both the entries.
    

    你想删除什么?你能解释一下吗。可能是同一个例子。您的代码并不清楚。@ArunKumar我正试图删除第二个代码窗口中提到的2个块。当脚本使用args::运行时,它应该从file.txt中删除相应的条目。谢谢,非常感谢。你能帮我再检查一遍代码吗?因为当脚本以“/del.py 192.168.0.10:80:somename1”的形式运行时,它不会从文件中删除3行或任何内容。我有几行主机地址:192.168.0.10:PORT:80/mode tcp/bind 192.168.0.10:80 somename1。请注意“/”对应一个新行,因为此窗口不允许我使用enter键。请帮助rahul,我想我们已经非常接近了。@bindo使用上面的代码,它会工作的。前面的代码有一些空格和制表符,我在上面的代码中修复了它。我又检查了一遍。非常感谢拉胡尔,你真是个天才。我刚刚试过代码,它工作得很好。解决这个问题的方法非常好,在变量中指定了所有行,而不是强调复杂的正则表达式模式。我稍微修改了一下代码,搜索和删除带有标签的行,到目前为止没有问题。谢谢。正则表达式会更好,但您可以稍后再尝试。另外,如果你喜欢这个答案,请把它投上去。非常感谢。如果您不介意的话,请将def getNextBlock的评论包括在内?我的主要目标是学习,这将非常有帮助。现在更有意义了。谢谢。我会再测试一次