Replace one column is txt file

Question:

I have several .txt files of annotation frame coordinates of objects in images.

The .txt file looks like below, the number of rows are not fixed and different for each .txt file.

2 0.063542 0.192593 0.021528 0.185185
2 0.106944 0.298148 0.030556 0.300000
2 0.186806 0.600000 0.061111 0.577778

Now I want to change the first column from 2 to 7 for in all these files, I’ve already tried:

for txtfile in txtfiles:

    with open(path + os.sep + txtfile, 'r') as file:
      filedata = file.read()
        
    # Replace the target string
    filedata2 = filedata.replace('2', '7')

However, ‘filedata’ here is a long string and all the ‘2’ will be replaced by ‘7’ (like 0.063542 becomes 0.063547). How can I replace only the first column?

Asked By: Elaine Yang

||

Answers:

Try:

'n'.join(['7' + line[line.index(' '):] for line in file])

Code example:

data = """
2 0.063542 0.192593 0.021528 0.185185
2 0.106944 0.298148 0.030556 0.300000
2 0.186806 0.600000 0.061111 0.577778
"""

lines = 'n'.join(['7' + line[line.index(' '):] for line in data.strip().splitlines()])
print(lines)

Output:

7 0.063542 0.192593 0.021528 0.185185
7 0.106944 0.298148 0.030556 0.300000
7 0.186806 0.600000 0.061111 0.577778

File Example

I would suggest trying something like this – this will write to a file ending in .out rather than update the existing file, though this can be changed easily.

from os.path import join

for txtfile in txtfiles:
    with open(join(path, txtfile), 'r') as file:
        # Replace the target string
        new_lines = 'n'.join(['7' + line[line.index(' '):] for line in file])
        with open(join(path, txtfile + '.out'), 'w') as out_file:
            out_file.write(new_lines)
Answered By: rv.kvetch

This is a delimited file. You’ll want to use the csv module for this. You are also not saving your output:

import csv

for txtfile in txtfiles:
    infile = os.path.join(path, txtfile)
    outfile = os.path.join(path, f'new_{txtfile}')

    with open(infile, newline='') as i, open(outfile, 'w', newline='') as o:
        reader = csv.reader(i, delimiter=' ')
        writer = csv.writer(o, delimiter=' ')

        for line in reader:
            line[0] = '7' # <------------- modify your value here
            writer.writerow(line) # <----- write your new data
Answered By: C.Nivs

You could use string indexing for each line in the file.

    with open(path + os.sep + txtfile, 'r') as file:
        lines = file.read().splitlines()  # get list of lines in file
    for lineNr in range(len(lines)):
        line = lines[lineNr]
        characters = list(line)  # get list of characters in line
        characters[0] = '7'      # set character in 1. [0] column to '7'
        lines[lineNr] = "".join(characters)  # join characters together
    newFile = "n".join(lines)   # join lines together

The conversion to a list of characters is necessary because strings in python don’t have write access to single characters.

Answered By: wediaklup
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.