37

Pythonでファイルの最後の行を削除するにはどうすればよいですか?

入力ファイルの例:

hello
world
foo
bar

出力ファイルの例:

hello
world
foo

ファイル内の行数を見つけるために次のコードを作成しましたが、特定の行番号を削除する方法がわかりません。

    try:
        file = open("file")
    except IOError:
        print "Failed to read file."
    countLines = len(file.readlines())
4

10 に答える 10

80

私は日常的に数ギガバイトのファイルを処理しているため、回答に記載されているようにループすることはできませんでした。私が使用するソリューション:

with open(sys.argv[1], "r+", encoding = "utf-8") as file:

    # Move the pointer (similar to a cursor in a text editor) to the end of the file
    file.seek(0, os.SEEK_END)

    # This code means the following code skips the very last character in the file -
    # i.e. in the case the last line is null we delete the last line
    # and the penultimate one
    pos = file.tell() - 1

    # Read each character in the file one at a time from the penultimate
    # character going backwards, searching for a newline character
    # If we find a new line, exit the search
    while pos > 0 and file.read(1) != "\n":
        pos -= 1
        file.seek(pos, os.SEEK_SET)

    # So long as we're not at the start of the file, delete all the characters ahead
    # of this position
    if pos > 0:
        file.seek(pos, os.SEEK_SET)
        file.truncate()
于 2012-04-23T23:32:06.717 に答える
21

上記のコードを使用して、次のようにすることができます:-

lines = file.readlines()
lines = lines[:-1]

これにより、最後の行を除くすべての行を含む行の配列が得られます。

于 2009-12-10T01:01:08.883 に答える
9

これはPythonを使用しませんが、これが必要な唯一のタスクである場合、Pythonはジョブに対して間違ったツールです。標準の*nixユーティリティを使用してhead、を実行できます。

head -n-1 filename > newfile

これにより、ファイル名の最後の行を除くすべてがnewfileにコピーされます。

于 2009-12-10T01:13:51.060 に答える
7

Pythonでこれを行う必要があり、リストのスライスでは不十分なほど大きなファイルがあると仮定すると、ファイルを1回パスするだけで実行できます。

last_line = None
for line in file:
    if last_line:
        print last_line # or write to a file, call a function, etc.
    last_line = line

世界で最も洗練されたコードではありませんが、それは仕事を成し遂げます。

基本的に、last_line変数を介してファイル内の各行をバッファリングし、各反復は前の反復行を出力します。

于 2009-12-10T01:18:05.857 に答える
4

これがLinuxユーザーのための私の解決策です:

import os 
file_path = 'test.txt'
os.system('sed -i "$ d" {0}'.format(file_path))

Pythonでファイルを読み取って反復する必要はありません。

于 2016-11-15T16:20:20.233 に答える
3

file.truncate()が機能するシステムでは、次のようなことができます。

file = open('file.txt', 'rb')
pos = next = 0
for line in file:
  pos = next # position of beginning of this line
  next += len(line) # compute position of beginning of next line
file = open('file.txt', 'ab')
file.truncate(pos)

私のテストによると、file.tell()は行ごとに読み取るときに機能しません。これは、おそらくバッファリングによって混乱するためです。これが、位置を把握するために線の長さを合計する理由です。これは、行区切り文字が「\n」で終わるシステムでのみ機能することに注意してください。

于 2009-12-10T01:15:03.587 に答える
2

以前の投稿からインスピレーションを得て、私はこれを提案します:

with open('file_name', 'r+') as f:
  f.seek(0, os.SEEK_END) 
  while f.tell() and f.read(1) != '\n':
    f.seek(-2, os.SEEK_CUR)
  f.truncate()
于 2017-01-03T06:47:21.320 に答える
0

headこれは、(コマンドのように)最後の「n」行をスキップできる、より一般的なメモリ効率の高いソリューションです。

import collections, fileinput
def head(filename, lines_to_delete=1):
    queue = collections.deque()
    lines_to_delete = max(0, lines_to_delete) 
    for line in fileinput.input(filename, inplace=True, backup='.bak'):
        queue.append(line)
        if lines_to_delete == 0:
            print queue.popleft(),
        else:
            lines_to_delete -= 1
    queue.clear()
于 2009-12-10T02:41:55.397 に答える
0

ファイル全体をメモリに丸呑みすることなく、別の方法があります

p=""
f=open("file")
for line in f:
    line=line.strip()
    print p
    p=line
f.close()
于 2009-12-10T02:32:11.730 に答える
0

私はそれをテストしていませんが(お願いします、それは嫌いではありません)、もっと速い方法があると思います。これはCソリューションのようなものですが、Pythonではかなり可能です。Pythonicでもありません。それは理論だと思います。

まず、ファイルのエンコーディングを知る必要があります。そのエンコーディングの文字が使用するバイト数(ASCIIでは1バイト)に変数を設定します。CHARsize(なぜそうではないのか)。おそらくASCIIファイルでは1バイトになるでしょう。

次に、ファイルのサイズを取得し、FILEsizeをそれに設定します。

FILEaddに(メモリ内の)ファイルのアドレスがあると仮定します。

FILEsizeFILEaddに追加します。

バックワードを移動し(-1 *** CHARsize **ずつインクリメント)、各CHARsizeバイトで\ n(またはシステムが使用する改行)をテストします。最初の\nに到達すると、ファイルの最初の行の先頭の位置になります。\nを\x1a(26、EOFのASCII、またはシステムの1つ/エンコーディングを含むもの)に置き換えます。

必要に応じてクリーンアップします(ファイルサイズを変更し、ファイルをタッチします)。

これが私が思うように機能する場合は、ファイル全体を最初から読む必要がなく、最後から読むので、多くの時間を節約できます。

于 2009-12-10T01:36:31.420 に答える