简体   繁体   中英

How to change a specific value of a specific key in text file using python

I would like to know how to replace a value of a specific key in a text file using python

I have this text file named passenger.txt have the following:

{'Civil ID':'1', 'Name':'Mike', 'DOB':'12/2/2000', 'Gender':'Male', 'Customs fine':'', 'Status':''}

I want to replace Status value to Sometext instead of blank, I already have a code but it replacing the key not the value. So, I'm wondering how to change the value not the key.

Here is the code:

passenger_db = "passenger.txt"
with open(passenger_db, "r+") as file:
  for single_line in f:
     x = single_line.replace('Status', 'Sometext')
     file.write(x)

I expect some one will help me.

lines = []
with open('passenger.txt') as f:
    for line in f.readlines():
        passenger = eval(line)

        # If you wish to update only certain strings
        if passenger['Civil ID'] == '1':
            passenger['Status'] = 'New status'

        lines.append(str(passenger))

with open('new_file.txt', 'w') as f:
    for line in lines:
        f.write(f'{line}\n')

Explanation:

I'm afraid the only option for you is the following:

  1. Read the whole file
  2. Convert each line to a python object
  3. Replace a key in the object
  4. Convert it back to a sting
  5. Write the result to the file again

You can use yaml module to parse each line to a dictionary then you can just update the value with key name

import yaml

with open('passenger.txt') as fp, open('output.txt', 'w') as fw:
  for line in fp:
    data = yaml.safe_load(line)
    data['Status'] = 'Some text'
    fw.write(str(data) + '\n')

But it's better to use json file with list of objects so you don't need to parse each line

Use RegEx substitution

If you don't feel like loading each line of data in Python dict object and modify the value (which is a totally fine way to do it), using RegEx would be a good alternative.

Regular expression is a very powerful tool when it comes to searching or manipulating string contents.

For the input txt file:

{'Civil ID':'1', 'Name':'Mike', 'DOB':'12/2/2000', 'Gender':'Male', 'Customs fine':'', 'Status':''}
{'Civil ID':'2', 'Name':'John', 'DOB':'12/2/2000', 'Gender':'Male', 'Customs fine':'', 'Status':'foo'}
{'Civil ID':'3', 'Name':'Mary', 'DOB':'12/2/2000', 'Gender':'Female', 'Customs fine':'', 'Status':'bar'}
import re


def set_values(filename: str, key: str, value: str):
    with open(filename) as f:
        text = f.read()
    updated_text = re.sub(f"(?<='{key}':').*(?='}})", value, text)
    with open(filename, 'w') as f:
        f.write(updated_text)


set_values('passenger.txt', 'Status', 'Sometext')

The script with replace all occurrences of the 'Status':'<any-text>' pattern with Sometext .

Result:

{'Civil ID':'1', 'Name':'Mike', 'DOB':'12/2/2000', 'Gender':'Male', 'Customs fine':'', 'Status':'Sometext'}
{'Civil ID':'2', 'Name':'John', 'DOB':'12/2/2000', 'Gender':'Male', 'Customs fine':'', 'Status':'Sometext'}
{'Civil ID':'3', 'Name':'Mary', 'DOB':'12/2/2000', 'Gender':'Female', 'Customs fine':'', 'Status':'Sometext'}

If you only want to modify one line instead of the whole file, just loop over the lines after reading the file and find the line you want to modify, then apply the regular expression substitution.

You can also tweak the RegEx pattern based on your need to substitute other content in the text file.

It's better to use JSON or pickle. But if you must:

import ast, pathlib
passenger_db = Path("passenger.txt")
data = ast.literal_eval(passenger_db.read_text())
data['Status'] = 'SomeText'
passenger_db.write_text(str(data))

One of many solutions.

Input file passenger.txt

{'Civil ID':'1', 'Name':'Mike', 'DOB':'12/2/2000', 'Gender':'Male', 'Customs fine':'', 'Status':''}

Code:

from ast import literal_eval
passenger_db = "passenger.txt"
with open(passenger_db) as file:
    lines = [literal_eval(x) for x in file]

with open(passenger_db, "w") as file:
    for line in lines:
        line['Status'] = "Sometext"
        file.write(str(line))

Result:

{'Civil ID': '1', 'Name': 'Mike', 'DOB': '12/2/2000', 'Gender': 'Male', 'Customs fine': '', 'Status': 'Sometext'}

Another way to solve it: The fileinput module of the Python standard library will rewrite a file inplace if you use the inplace=1 parameter:

import fileinput
import sys
passenger_db = "passenger.txt"
for line in fileinput.input('passenger.txt', inplace=1):
    sys.stdout.write(line.replace("'Status': ''", "'Status': 'Sometext'"))

Result:

{'Civil ID': '1', 'Name': 'Mike', 'DOB': '12/2/2000', 'Gender': 'Male', 'Customs fine': '', 'Status': 'Sometext'}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM