2017-10-05 193 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)