2017-04-25 2 views
1

파일에서 한 줄의 블록을 삭제하는 방법에 대해 고민하고 있습니다. 코드는 다음과 같습니다파이썬 파일에서 한 줄의 블록 삭제하기

#!/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 : 포트 : 이름). 스크립트가 ./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 두 번째 코드 창에서 언급 한 두 블록을 삭제하려고합니다. 스크립트가 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