2017-04-25 4 views
1

Ich habe Mühe herauszufinden, wie ich einen Block von Zeilen aus einer Datei löschen sollte. Unten ist der CodePython löscht einen Block von Zeilen aus einer Datei

#!/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() 

Wie Sie sehen können, füge ich die file.txt mit Benutzereingaben an. (Format: IP: Port: Name). Datei wird im folgenden Einträge enthalten, wenn das Skript excuted als ./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 

Jetzt möchte ich die Zeile (n) aus der Datei löschen. txt, wenn die Benutzereingabe auf die gleiche Weise erfolgt. Wenn der obige Code ausgeführt wird, passiert nichts. Ich bin ein Anfänger und wirklich dankbar, wenn Sie mir helfen zu verstehen. Diese Frage bezieht sich auf python multiple user args

+0

Sie möchten was löschen? Kannst du etwas erklären? Kann mit dem gleichen Beispiel sein. Es ist nicht wirklich klar aus deinem Code. – arunk2

+0

@ArunKumar Ich versuche, diese 2 Blöcke im zweiten Codefenster zu löschen. Wenn das Skript mit Argumenten : : ausgeführt wird, sollte es die entsprechenden Einträge aus file.txt löschen. Vielen Dank. – bindo

Antwort

1

Lassen Sie mich auf die kleinen Dinge hinweisen, die Sie vermissen.

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() 
  1. Sie öffnen die Datei in der Schleife und Schließen außen. Das Dateiobjekt liegt außerhalb des Gültigkeitsbereichs. Verwenden Sie with, die den Kontext automatisch für Sie behandelt.

  2. Es ist eine schlechte Idee, eine Datei innerhalb einer Schleife zu öffnen, da so viele Dateideskriptoren erstellt werden, die sehr viele Ressourcen verbrauchen.

  3. Sie haben nie erwähnt, was YY ist, wenn Sie schreiben.

  4. Sie Zeilen hier löschen können, wie Sie mehrere Zeilen auf einmal löschen versuchen, so sollte d = f.readlines()d = f.read()

sein Unterhalb der den Code aktualisiert wird.

#!/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. 
+0

vielen Dank. kannst du den code nochmal für mich überprüfen, weil es die 3 zeilen oder gar nichts aus der datei löscht, wenn das skript als "./del.py 192.168.0.10:80:somename1" ausgeführt wird. Ich habe die Zeilen Hostadresse: 192.168.0.10: PORT: 80/mode tcp/bind 192.168.0.10:80 somename1. Bitte beachten Sie, dass "/" einer neuen Zeile entspricht, da ich in diesem Fenster die Eingabetaste nicht benutzen kann. Bitte hilf rahul ich denke wir sind sehr sehr nah dran. – bindo

+0

@bindo verwenden Sie obigen Code, es wird funktionieren. Der vorherige Code, den Sie hatten, hatte einige Leerzeichen und Tabs und ich habe es in dem obigen Code behoben. Es funktioniert, ich habe es noch einmal überprüft. – Rahul

+0

Vielen Dank Rahul, du bist wirklich ein Genie.Ich habe gerade den Code ausprobiert und es funktioniert perfekt. Die Art und Weise, wie Sie das Problem gelöst haben, ist ausgezeichnet, wenn Sie alle Zeilen in einer Variablen angegeben haben, anstatt sich über komplexe Regex-Muster zu stressen. Ich habe mit dem Code ein wenig geplumpst, um Zeilen mit Tabs zu suchen und zu löschen, bisher keine Probleme. – bindo

0

Es gibt mehrere Möglichkeiten, dies zu tun. Ich habe versucht, eine neue Datei zu erstellen und alle Blöcke zu verlassen. Sie können die alte Datei löschen und die neue Datei als alte Datei umbenennen. Folgendes ist der Arbeitscode für dasselbe.

#!/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 

Hoffe es hilft!

+0

Vielen Dank. Wenn es Ihnen nichts ausmacht, können Sie bitte Kommentare von def getNextBlock hinzufügen? Mein Hauptziel ist es zu lernen und es wird sehr hilfreich sein. – bindo

+0

Macht jetzt viel mehr Sinn. Danke vielmals. Ich werde das nochmal testen – bindo

Verwandte Themen