2017-04-25 2 views
1

ファイルから行のブロックを削除する方法については、私は苦労しています。コードは以下の通りですPythonファイルから行のブロックを削除する

#!/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にユーザー入力を追加しています。すなわち(形式:ip:port:name)。スクリプトは今、私は、ファイルからの行(複数可)を削除したい./script.pyが

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 

を192.168.0.10:80:string 192.168.0.10:80:stringとしてexcutedされている場合、ファイルは、エントリの下に含まれています。ユーザ入力が同じように与えられたときには、txt。上記のコードを実行すると何も起こりません。私は初心者であり、あなたが私の理解を助けるならば本当に気持ち良いです。この質問は、python multiple user args

+0

何を削除しますか?あなたは少し説明できますか?同じ例があるかもしれません。あなたのコードからはそれほど明確ではありません。 – arunk2

+0

@ArunKumar 2番目のコードウィンドウに記載されている2つのブロックを削除しようとしています。スクリプトがargs で実行されると、対応するエントリがfile.txtから削除されます。ありがとう。 – bindo

答えて

1

あなたが欠けている小さなものを指摘しましょう。

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. あなたは、ループ内でファイルを開いて、外に閉じ。ファイルオブジェクトが範囲外です。自動的にコンテキストを処理するwithを使用してください。

  2. 多くのリソースを消費するファイル記述子が非常に多く作成されるため、ループ内でファイルを開くのは悪い考えです。

  3. 書き込み中はYYは何も言及していません。あなたが一度に複数の行を削除しようとしているとして、あなたはここで行を削除することができます

  4. は、そう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. 
+0

ありがとうございます。スクリプトが "./del.py 192.168.0.10:80:somename1"として実行されたときにファイルから3行または何かを削除しないでください。私は行を持っているホストアドレス:192.168.0.10:ポート:80 /モードTCP /バインド192.168.0.10:80 somename1。親切に "/"は新しい行に対応していますので、このウィンドウでEnterキーを使用できません。私は非常に近いと思うrahulを助けてください。 – bindo

+0

@bindo上記のコードを使用すると動作します。以前のコードにはスペースとタブがあり、上のコードで修正しました。私はそれを再びチェックして働いています。 – Rahul

+0

あまりにもrahulありがとう、本当に天才です。私はちょうどコードとその完璧に動作しようとしました。複雑な正規表現パターンを強調するのではなく、変数内のすべての行を指定したところで、問題を解決した方法が優れています。私は、タブで行を検索したり削除したりするために、少しコードを手書きしていましたが、これまでのところ問題はありません。 – bindo

0

に関連しています。複数の方法があります。私はすべてのブロックを残して新しいファイルを作成しようとしました。古いファイルを削除し、新しいファイルの名前を古いファイルに変更することができます。 次のコードは同じものです。

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

希望すると助かります!

+0

ありがとうございます。 def getNextBlockからのコメントを含めてください。私の主な目的は学ぶことであり、本当に役に立ちます。 – bindo

+0

今より多くの意味があります。どうもありがとう。これをもう一度試してみます – bindo

関連する問題