2017-10-05 185 views
0

我試圖用python腳本管理主機文件。我是python的新手,如果找到匹配的話,我很難弄清楚如何替換一條線。例如,如果地址在網站的主機文件中發生更改,我希望腳本找到它並將其更改回來。謝謝你的幫助。Python替換文本文件中的行

import os 
import time 

#location to the host file to read and write to 
hosts_path=r"C:\Windows\System32\drivers\etc\hosts" 
#the address I want for the sites 
redirect="0.0.0.0" 
#the websites that I will set the address for 
website_list=["portal.citidirect.com","www.bcinet.nc","secure.banque-tahiti.pf","www.bancatlan.hn","www.bancentro.com.ni","www.davivienda.com.sv","www.davivienda.cr","cmo.cibc.com","www.bi.com.gt","empresas.banistmo.com","online.belizebank.com","online.westernunion.com","archive.clickatell.com"] 

#continuous loop 
while True: 
    with open(hosts_path,'r+') as file: 
     content=file.read() 
#for each of the websites in the list above make sure they are in the host file with the correct address 
     for website in website_list: 
      site=redirect+" "+ website 
#here is where I have an issue, if the website is in the host file but with the wrong address I want to write over the line, instead the program is adding it to the end of the file 
      if website in content: 
       if site in content: 
        pass 
       else: 
        file.write(site) 
      else: 
       file.write("\n"+site) 
    time.sleep(300) 

    os.system('ipconfig /flushdns') 
+1

將更改後的行寫入_new_文件,然後在完成時將文件重命名爲舊名稱會更容易。在現有位置更新現有文件非常困難。 –

+0

這裏的問題是您正在讀取整個文件,然後掃描數據。當然,使用這種方法仍然可以解決這個問題,但更快更簡單的方法是按行 –

+0

掃描文件行謝謝你的迴應。約翰戈登我喜歡使用另一個文件的想法。 – jbvo

回答

1

您需要將文件讀取到列表中,然後如果需要將列表的索引更改,然後將列表寫回文件。你在做什麼只是寫在文件的末尾。您不能直接更改文件。您需要將更改記錄在列表中,然後編寫列表。我最終不得不重寫很多代碼。這是完整的腳本。我不確定os.system('ipconfig /flushdns')正在完成什麼,所以我刪除了它。您可以輕鬆地將其添加回您想要的位置。

#!/usr/bin/env python3.6 

import time 

hosts_path = r"C:\\Windows\\System32\\drivers\\etc\\hosts" 
redirect = "0.0.0.0" 
website_list = [ 
    "portal.citidirect.com", 
    "www.bcinet.nc", 
    "secure.banque-tahiti.pf", 
    "www.bancatlan.hn", 
    "www.bancentro.com.ni", 
    "www.davivienda.com.sv", 
    "www.davivienda.cr", 
    "cmo.cibc.com", 
    "www.bi.com.gt", 
    "empresas.banistmo.com", 
    "online.belizebank.com", 
    "online.westernunion.com", 
    "archive.clickatell.com"] 


def substring_in_list(the_list, substring): 
    for s in the_list: 
     if substring in s: 
      return True 
    return False 


def write_websites(): 
    with open(hosts_path, 'r') as file: 
     content = file.readlines() 
    for website in website_list: 
     site = "{} {}\n".format(redirect, website) 
     if not substring_in_list(content, website): 
      content.append(site) 
     else: 
      for line in content: 
       if site in line: 
        pass 
       elif website in line: 
        line = site 
    with open(hosts_path, "w") as file: 
     file.writelines(content) 


while True: 
    write_websites() 
    time.sleep(300) 
+0

感謝您花時間回覆。我喜歡你如何將它分成單獨的功能。 – jbvo

+0

不客氣。函數只是一個好習慣。總是樂於幫助! – Steampunkery

0

那麼,你打算給每個沒有出現在你的網站列表中的站點分配相同的IP地址?

下面將取代什麼是你最while循環內:每行的

# Read in all the lines from the host file, 
# splitting each into hostname, IPaddr and aliases (if any), 
# and trimming off leading and trailing whitespace from 
# each of these components. 
host_lines = [[component.strip() for component in line.split(None, 2)] for line in open(host_path).readlines()] 

# Process each of the original lines. 
for line in host_lines: 
    # Is the site in our list? 
    if line[1] in website_list: 
     # Make sure the address is correct ... 
     if line[0] != redirect: 
      line[0] == redirect 

     # We can remove this from the websites list. 
     website_list.remove(line[1]) 

# Whatever sites are left in websites don't appear 
# in the hosts file. Add lines for these to host_lines 
host_lines.extend([[redirect, site] for site in website_list]) 

# Write the host_lines back out to the hosts file: 
open(hosts_path, 'w').write("\n".join([" ".join(line) for line in host_lines])) 

最右邊join膠水的成分回連成一個字符串。它的左邊的join將所有這些字符串與它們之間的換行符粘在一起,並將此整個字符串寫入文件。

我不得不說,這看起來像一個相當複雜甚至危險的方式來確保您的主機文件保持最新和準確。每隔五分鐘從一個可信任主機獲得一個cron作業scp這個已知好的主機文件,不是更好嗎?

+0

這是一個臨時的解決方案,可以阻止少數機器上的幾個網站,同時我們正致力於實現將來處理它的設備。我喜歡使用單獨的文件的想法。 – jbvo

0

我最終混合了一些響應來創建一個新文件,以使用如下所示的函數替換當前主機文件。除了這段代碼,我使用pyinstaller把它變成一個EXE,然後我設置該EXE作爲自動啓動服務運行。

#!/usr/bin/env python3.6 

import os 
import shutil 
import time 

temp_file = r"c:\temp\Web\hosts" 
temp_directory="c:\temp\Web" 
hosts_path = r"C:\Windows\System32\drivers\etc\hosts" 
websites = ('''# Copyright (c) 1993-2009 Microsoft Corp. 
# 
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows. 
# 
# This file contains the mappings of IP addresses to host names. Each 
# entry should be kept on an individual line. The IP address should 
# be placed in the first column followed by the corresponding host name. 
# The IP address and the host name should be separated by at least one 
# space. 
# 
# Additionally, comments (such as these) may be inserted on individual 
# lines or following the machine name denoted by a '#' symbol. 
# 
# For example: 
# 
#  102.54.94.97  rhino.acme.com   # source server 
#  38.25.63.10  x.acme.com    # x client host 

# localhost name resolution is handled within DNS itself. 
# 127.0.0.1  localhost 
# ::1    localhost 
0.0.0.0 portal.citidirect.com 
0.0.0.0 www.bcinet.nc 
0.0.0.0 secure.banque-tahiti.pf 
0.0.0.0 www.bancatlan.hn 
0.0.0.0 www.bancentro.com.ni 
0.0.0.0 www.davivienda.com.sv 
0.0.0.0 www.davivienda.cr 
0.0.0.0 cmo.cibc.com 
0.0.0.0 www.bi.com.gt 
0.0.0.0 empresas.banistmo.com 
0.0.0.0 online.belizebank.com 
0.0.0.0 online.westernunion.com 
0.0.0.0 archive.clickatell.com''') 


def write_websites(): 
    with open(temp_file, 'w+') as file: 
     file.write(websites) 


while True: 
    if not os.path.exists(temp_directory): 
     os.makedirs(temp_directory) 
    try: 
     os.remove(temp_file) 
    except OSError: 
     pass 

    write_websites() 

    try: 
     os.remove(hosts_path) 
    except OSError: 
     pass 

    try: 
     shutil.move(temp_file,hosts_path) 
    except OSError: 
     pass 

    os.system('ipconfig /flushdns') 
    time.sleep(300)