使用文件方法在多个文件中编辑一行 - python

时间:2014-06-05 15:58:13

标签: python python-2.7

这是我的代码:

“常数”

import os
import tempfile
import shutil

file_domini = open("ns_list.txt", "r")    #contains a list of ns
dir_name = '/var/named/'
filename_suffix = '.zone'
bad_words = ['TTL']
prep_str = "$TTL 1d"

3个功能:

def line_prepender(filename, string):       #add a string on file top
    with open(filename, 'r+') as f:
        content = f.read()
        f.seek(0, 0)
        f.write(string.rstrip('\r\n') + '\n' + content)


def create_temporary_copy(path):            #create a copy of path using temp files
    temp_dir = tempfile.gettempdir()
    temp_path = os.path.join(temp_dir, 'zone_file.tmp')
    shutil.copy2(path,  temp_path)
    return temp_path


def zone_file_checker(percorso_file):       #add/edit/check some condition of zone file
    file_di_zona = open(filename, 'r')      #"file di zona" means zone file
    text = file_di_zona.read()

    # copy file_di_zona on tmp and remove lines containing $TTL
    # occorrenze di TTL
    with open(create_temporary_copy(filename), 'r+') as tmp:

        for line in text:
            # search and remove eventually wrong TTL strings
            if not any(bad_word in line for bad_word in bad_words):
                tmp.write(line)

            # add $TTL 1d in prepending
            line_prepender(tmp, prep_str)
            #continue

主要问题

            #continue
            #this 4 lines
            # add @ before mx records
            if line.lstrip().startswith('IN') and 'MX' in line: 
                line = "@" + line[1:]
                tmp.write(line)

        print tmp
        tmp.close()
    file_di_zona.close()

主要功能:

for riga in file_domini:                   #"riga" means "line"
    # modifico casi particolari
    if not riga.startswith('('):
        # replace to fit file name syntax
        zone_name = riga.replace('.', '_').replace('\n', '')

        filename = dir_name + zone_name + filename_suffix
        print filename

        count = 0
        try:
            zone_file_checker(filename)

        except IOError as e:
            count += 1
            # print filename + ":"
            print "    I/O error({0}): {1}".format(e.errno, e.strerror)

if count > 0:
            print "IOError: %d domain names not found" % count

file_domini.close()

你可以在第三个子功能的评论中看到,

# add @ before mx records
if line.lstrip().startswith('IN') and 'MX' in line:     #the main problem
    line = "@" + line[1:]
    tmp.write(line)

它不会写入文件。

这是区域文件的示例:

              IN      MX    20 mail2.example.com. 
              IN  MX    50 mail3              
example.com.  IN      A     192.0.2.1             
              IN      AAAA  2001:db8:10::1       
ns            IN  A     192.0.2.2             
              IN      AAAA  2001:db8:10::2     

这是ns_list.txt

的示例
example1.com
( dns.example.it. )
( dns1.example.it. )
example2.eu
( dns1.example.it. )
( dns.example.it. )
example3.mobi
( dns2.example.it. )
( dns.example.it. )
example4.com
( dns1.novanet.it. )
( dns.novanet.it. )

有一些文件名为sitename_com.zone,sitename_it.zone,sitename_ext.zone,对应每个域名(example1.com,example2.eu,ecc)

我需要解决的主要问题是我不能写这些文件的副本(临时)或直接写在它们上。

3 个答案:

答案 0 :(得分:1)

def zone_file_checker(filename):
    """ aggiunge, modifica e verifica
   le condizioni per cui il file di zona
    sia corretto e non dia problemi
    in fase di migrazione"""
    text = open(filename, 'r')


    # copio file_di_zona su tmp, e rimuovo righe di eventuali
    # occorrenze di TTL
    with open(create_temporary_copy(filename), 'r+') as tmp:

        for line in text:

            # vedi context manager e any


if not any(bad_word in line for bad_word in bad_words):
                if line.lstrip().startswith('IN') and 'MX' in line:
                    line = "@" + line[1:]
                    tmp.write(line)
                else:
                    tmp.write(line)

            # aggiungo $TTL 1d in prepending
            # line_prepender(tmp, prep_str)

            # aggiungo @ davanti agli mx records




        # esco
        print tmp
        tmp.close()
    text.close()
你犯了2个错误

1)

file_di_zona = open(filename, 'r')      #"file di zona" means zone file
    text = file_di_zona.read()

解决方案使用下面的行不读。 :

  

text = open(filename,'r')

2)两个ifs用于坏词和行

if not any(bad_word in line for bad_word in bad_words):


     if line.lstrip().startswith('IN') and 'MX' in line:
                        line = "@" + line[1:]
                        tmp.write(line)
                    else:
                        tmp.write(line)

最后我不知道你为什么使用行预编程器。不要用它。

答案 1 :(得分:0)

致电

        line_prepender(tmp, prep_str)

tmp不是文件名,正如line_prepender所期望的那样。这是事情开始崩溃的一个可能的地方。

答案 2 :(得分:0)

我编辑了一些代码,现在工作正常

def zone_file_checker(filename):

zone_file = open(filename, 'r')

# copio file_di_zona su tmp, e rimuovo righe di eventuali
# occorrenze di TTL
with open(create_temporary_copy(filename), 'r+') as tmp:
    line_prepender(tmp, prep_str)
    # print("byte #" + str(tmp.tell()))
    for line in zone_file:  # if you put tmp it doesn't print @ before mx

        # vedi context manager e any
        if not '$TTL' in line:
            # aggiungo @ davanti agli mx records
            if line.lstrip().startswith('IN') and 'MX' in line:
                line = "@" + line[1:]
                tmp.write(line)
            else:
                tmp.write(line)

    tmp.seek(0, 0)
    # print(tmp.tell())
    print(tmp.read())

    tmp.close()
zone_file.close()

和预装功能

def line_prepender(filename, stringa):

filename.seek(0, 0)
filename.writelines([stringa.rstrip('\r\n') + '\n'])