Удалить содержимое существующего файла и снова записать содержимое

Эксперты, проблема является распространенной, и я пробовал, основываясь на решениях и примерах в SO, но все еще имею проблему с записью вывода на печать всех моих устройств в файл. У меня есть тест с использованием нескольких методов, и большую часть времени у меня есть только последняя строка вывода в моем текстовом файле. Проблема ниже почти такая же, как у меня... но мне не повезло.

Как удалить содержимое файла перед записью в него в скрипте Python?

Я тестирую скрипт для запуска определенной команды в зависимости от типа устройства. Если устройства A запускают команду A, если устройства B запускают команду B, если устройство C запускает команду c. Список устройств в текстовом файле (список имеет тип и IP-адрес). Когда я использую «w» содержимое файла только в последней строке, но когда я использую «a», он сохраняет все содержимое всех устройств в списке, но когда я снова запускаю скрипт, он будет продолжать писать на последний указатель и таким образом, я получил дублированный контент... он добавляется и продолжает добавляться.

при использовании outFileName выходное содержимое "w" принимает только содержимое последней строки

OUTPUT CONTENT for device type C IP 10.2.10.12

при использовании outFileName вывод содержимого "a" при первом запуске сценария выполняется следующим образом.

OUTPUT CONTENT for device type A IP 192.168.100.100
OUTPUT CONTENT for device type A IP 192.168.100.110
OUTPUT CONTENT for device type B IP 10.1.10.100
OUTPUT CONTENT for device type C IP 10.2.10.10
OUTPUT CONTENT for device type C IP 10.2.10.11
OUTPUT CONTENT for device type C IP 10.2.10.12

при запуске скрипта во второй раз ... файл содержит дубликаты следующим образом

OUTPUT CONTENT for device type A IP 192.168.100.100
OUTPUT CONTENT for device type A IP 192.168.100.110
OUTPUT CONTENT for device type B IP 10.1.10.100
OUTPUT CONTENT for device type C IP 10.2.10.10
OUTPUT CONTENT for device type C IP 10.2.10.11
OUTPUT CONTENT for device type C IP 10.2.10.12
OUTPUT CONTENT for device type A IP 192.168.100.100
OUTPUT CONTENT for device type A IP 192.168.100.110
OUTPUT CONTENT for device type B IP 10.1.10.100
OUTPUT CONTENT for device type C IP 10.2.10.10
OUTPUT CONTENT for device type C IP 10.2.10.11
OUTPUT CONTENT for device type C IP 10.2.10.12

Скрипт выглядит следующим образом

#Define functions for each device_type
def type_A(ip):
    return{
        'device_type': 'A',
        'ip': ip,
        'username': 'usr10',
        'password': 'password',
        }

def type_B(ip):
    return{
        'device_type': 'B',
        'ip': ip,
        'username': 'usr10',
        'password': 'password',
        }

def type_C(ip):
    return{
        'device_type': 'C',
        'ip': ip,
        'username': 'usr10',
        'password': 'password',
        }

#Function to create output text file
def writeOutFile(outFileName, string):
    with open(outFileName, "w") as f:
       outfile = f.write(string)

#Open Text file that contain device type and ip address
deviceFile = open('devices.txt','r')

#Create list llist for each line in the file.  
#The first item is the device type, 
#The second item is the IP address
for line in deviceFile:
    llist = line.split()
    ipAd = llist[1]

    #Check the first item of the list to determine device type and set 
    #variables
    if llist[0] == 'A':
        dvs = type_A(ipAd)
        sendCommand = 'command for device type A'
    elif llist[0] == 'B':
        dvs = type_B(ipAd)
        sendCommand = 'command for device type B'
    elif llist[0] == 'C':
        dvs = type_C(ipAd)
        sendCommand = 'command for device type c'
    else:
        print("no valid device type")
        break

    dvs_connect = ConnectHandler(**dvs)
    sendCommand = (dvs_connect.send_command(sendCommand))
    #This print all the devices output on the terminal
    print(sendCommand)

    #Generate output file
    outFileName = "outputFile.txt"

    #function call to write the output string into a text file
    writeOutFile(outFileName, sendCommand)

    dvs_connect.disconnect()

deviceFile.close()

список устройств.txt

A 192.168.100.100
A 192.168.100.110
B 10.1.10.100
C 10.2.10.10
C 10.2.10.11
C 10.2.10.12

outputFile.txt Выходной файл содержит только содержимое последней строки ...выходное содержимое A и B уже перезаписано.

OUTPUT CONTENT for device type C IP 10.2.10.12

Я ожидаю, сколько раз я запускаю скрипт, он будет перезаписывать существующее содержимое текстового файла, но не дублировать... если у меня есть 6 устройств в моем списке devices.txt... это означает, что у меня должно быть 6 выходных данных устройства в моем текстовом файле выход. Выходной файл должен быть таким, как показано ниже

OUTPUT CONTENT for device type A IP 192.168.100.100
OUTPUT CONTENT for device type A IP 192.168.100.110
OUTPUT CONTENT for device type B IP 10.1.10.100
OUTPUT CONTENT for device type C IP 10.2.10.10
OUTPUT CONTENT for device type C IP 10.2.10.11
OUTPUT CONTENT for device type C IP 10.2.10.12

Я действительно надеюсь, что кто-то может мне помочь .. пожалуйста, помогите. Спасибо.


person chenoi    schedule 20.10.2019    source источник
comment
проблема не в открытии файла в разных режимах, вы можете сохранить информацию о файле в файле рассола, когда вы его запускаете, если вы хотите сохранить IP-адрес устройства, проверьте, присутствует ли он в файле дампа рассола, если поэтому пропустите, иначе напишите в текстовый файл и в конце обновите файл рассола с выводом   -  person Surya Tej    schedule 20.10.2019
comment
Спасибо, сэр... можете показать, как это делается?   -  person chenoi    schedule 20.10.2019


Ответы (1)


Открытие в режиме 'w' усекает файл, если он существует, а режим 'a' дополняет его.

Ваша проблема заключается в том, что вы повторно открываете файл в режиме 'w' для каждой строки вывода. Каждый раз, когда вы повторно открываете файл, вы стираете предыдущее содержимое.

Есть два решения этой проблемы:

  1. Предпочтительным решением было бы открыть файл один раз в вашем скрипте и использовать существующий дескриптор файла для записи в него нескольких строк вместо того, чтобы открывать новый дескриптор файла для каждой строки вывода.
  2. Вы также можете открыть файл один раз с режимом 'w' в начале вашего скрипта, а затем использовать режим 'a' (но это хак).

Один из способов реализовать первый вариант — открыть файл прямо перед основным циклом:

with open("outputFile.txt", "w") as f:
    for line in deviceFile:
        # ...

        # Replace this line:
        # writeOutFile(outFileName, sendCommand)
        # With this one:
        f.write(sendCommand)

Возможно, вам придется добавить новую строку ("\n") к этой строке перед ее записью; Я не вижу, как dvs_connect.send_command() форматирует свой вывод.

person cdhowie    schedule 20.10.2019
comment
Спасибо за ваш ответ, сэр .... вариант 1 - это тот, который я пытаюсь сделать ... я пробовал открывать файл в цикле for, но еще не открывал файл перед циклом for ... спасибо за ваш ответ и пример. Я попробую это. - person chenoi; 20.10.2019