user1871869
user1871869

Reputation: 3367

Easy way to replace last character in file?

I simply want to replace the last character in my file. The reason is because when I write to my file, at the last point in which I write to the file, there is an extra , that is included at the end. I simply don't want to write that , at the end, but rather would want to replace it with a ] if possible. Here is my attempt:

reader = csv.DictReader(open(restaurantsCsv), delimiter=';')
  with open(fileName, 'w+') as textFile:
    textFile.write('[')
    for row in reader:
      newRow = {}
      for key, value in row.items():
        if key == 'stars_count' or key == 'reviews_count':
          newRow[key] = float(value)
        else:
          newRow[key] = value
      textFile.write(json.dumps(newRow) + ',')
    textFile.seek(-1, os.SEEK_END)
    textFile.truncate()
    textFile.write(']')

It all works properly until I get to textFile.seek(-1, os.SEEK_END) where I want to seek the end of the file and I want to remove that last , in the file, but I get an error saying io.UnsupportedOperation: can't do nonzero end-relative seeks. Therefore, I made it so that my file opens with wb+ parameters, but if I do that, then I can only write bytes to my file, and not strings. Is there any way I can simply replace the last character in my file with a ] instead of a ,? I know I can simply open the file to read, truncate the file, then open the file again to write the last ] but that seems inefficient (as shown here):

   with open(filename, 'rb+') as filehandle:
     filehandle.seek(-1, os.SEEK_END)
     filehandle.truncate()

   with open(filename, 'a') as filehandle:
    filehandle.write(']')

Any help would be appreciated. Thanks!

Upvotes: 6

Views: 9329

Answers (3)

Blender
Blender

Reputation: 298206

You can slightly modify your approach and instead of appending a comma at the end of each line, you just prepend a comma to every line but the first:

reader = csv.DictReader(open(restaurantsCsv), delimiter=';')

with open(fileName, 'w+') as text_file:
    text_file.write('[')

    for index, row in enumerate(reader):
        new_row = {}

        for key, value in row.items():
            if key in ('stars_count', 'reviews_count'):
                new_row[key] = float(value)
            else:
                new_row[key] = value

        if index != 0:
            text_file.write(',')

        text_file.write(json.dumps(new_row))

    text_file.write(']')

Upvotes: 5

wwii
wwii

Reputation: 23753

As suggested by @Chris, accumulate all the new rows in a list then write all those row once. Then you won't have that pesky hanging comma.

......
    rows = []
    for row in reader:
        newRow = {}
        for key, value in row.items():
            if key == 'stars_count' or key == 'reviews_count':
                newRow[key] = float(value)
            else:
                newRow[key] = value
        rows.append(newRow)
    textFile.write(json.dumps(rows))

Upvotes: 1

Mohammad Yusuf
Mohammad Yusuf

Reputation: 17064

To replace last character of the file, i.e. last character of last line.

To see if its working properly

sed '$ s/.$/]/' file_name

To replace the last character of last line i.e comma in your case with ']' and change the file.

sed -i '$ s/.$/]/' file_name

To run from within python

import os
print os.system("sed -i '$ s/.$/]/' file_name")

Upvotes: 2

Related Questions