web-dev-qa-db-ja.com

Python-ファイルの最後の文字を削除する

インターネット全体を見て、私はこれに来ました。

次のようなテキストファイルを既に作成したとします。Hello World

さて、このテキストファイルから最後の文字(この場合はd)を削除します。

したがって、テキストファイルは次のようになります。Hello Worl

しかし、私はこれを行う方法がわかりません。

私が欲しいのは、多かれ少なかれ、HDD上のテキストファイル用の単一のバックスペース機能だけです。

私が使用しているので、これはLinuxで動作する必要があります。

34
user2681562

file.seek() を使用して末尾から1ポジションをシークし、次に file.truncate() を使用してファイルの残りを削除します。

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

Martijnの受け入れられた答えは簡単であり、一種の作品ですが、次のようなテキストファイルを考慮していません。

  • TF-8エンコーディング英語以外の文字を含む(Python 3)のテキストファイルのデフォルトエンコーディングです)
  • 1つファイルの最後の改行文字(これはvimgeditなどのLinuxエディターのデフォルトです)

テキストファイルに英語以外の文字が含まれている場合、これまでに提供された回答はいずれも機能しません。

以下は、両方の問題を解決する例です。これにより、ファイルの末尾から複数の文字を削除することもできます。

import os


def truncate_utf8_chars(filename, count, ignore_newlines=True):
    """
    Truncates last `count` characters of a text file encoded in UTF-8.
    :param filename: The path to the text file to read
    :param count: Number of UTF-8 characters to remove from the end of the file
    :param ignore_newlines: Set to true, if the newline character at the end of the file should be ignored
    """
    with open(filename, 'rb+') as f:
        last_char = None

        size = os.fstat(f.fileno()).st_size

        offset = 1
        chars = 0
        while offset <= size:
            f.seek(-offset, os.SEEK_END)
            b = ord(f.read(1))

            if ignore_newlines:
                if b == 0x0D or b == 0x0A:
                    offset += 1
                    continue

            if b & 0b10000000 == 0 or b & 0b11000000 == 0b11000000:
                # This is the first byte of a UTF8 character
                chars += 1
                if chars == count:
                    # When `count` number of characters have been found, move current position back
                    # with one byte (to include the byte just checked) and truncate the file
                    f.seek(-1, os.SEEK_CUR)
                    f.truncate()
                    return
            offset += 1

使い方:

  • UTF-8でエンコードされたテキストファイルの最後の数バイトのみをバイナリモードで読み取ります
  • バイトを逆方向に反復し、UTF-8文字の開始を探します
  • 文字(改行とは異なる)が見つかったら、それをテキストファイルの最後の文字として返します。

サンプルテキストファイル-bg.txt

Здравей свят

使い方:

filename = 'bg.txt'
print('Before truncate:', open(filename).read())
truncate_utf8_chars(filename, 1)
print('After truncate:', open(filename).read())

出力:

Before truncate: Здравей свят
After truncate: Здравей свя

これは、UTF-8とASCIIエンコードされたファイルの両方で機能します。

7
quasoft

「w」のアクセス権しか持たないバイナリモードでファイルを読み取らない場合は、次の方法をお勧めします。

_f.seek(f.tell() - 1, os.SEEK_SET)
f.write('')
_

上記のこのコードでは、f.seek()は、 'b'アクセスを持っていないf.tell() b/cのみを受け入れます。次に、カーソルを最後の要素の開始点に設定できます。その後、空の文字列で最後の要素を削除できます。

5
metinsenturk
with open(urfile, 'rb+') as f:
    f.seek(0,2)                 # end of file
    size=f.tell()               # the size...
    f.truncate(size-1)          # truncate at that size - how ever many characters

Unixファイルの行末の多くは 不正または不正 文字カウントを返すため、Windowsでは必ずバイナリモードを使用してください。

4
dawg

ここは汚い方法です(消去と再作成)...これを使用することはお勧めしませんが、このようにすることは可能です..

x = open("file").read()
os.remove("file")
open("file").write(x[:-1])
0
vins mv