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?
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)
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
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.
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?
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)
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
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.