GNU/Linux >> Belajar Linux >  >> Linux

Hapus dua baris terakhir dari file teks yang sangat besar secara efisien

Saya belum mencoba ini pada file besar untuk melihat seberapa cepatnya, tetapi seharusnya cukup cepat.

Untuk menggunakan skrip untuk menghapus baris dari akhir file:

./shorten.py 2 large_file.txt

Itu mencari ke akhir file, memeriksa untuk memastikan karakter terakhir adalah baris baru, kemudian membaca setiap karakter satu per satu mundur sampai ditemukan tiga baris baru dan memotong file tepat setelah titik itu. Perubahan dilakukan pada tempatnya.

Edit: Saya telah menambahkan versi Python 2.4 di bagian bawah.

Ini adalah versi untuk Python 2.5/2.6:

#!/usr/bin/env python2.5
from __future__ import with_statement
# also tested with Python 2.6

import os, sys

if len(sys.argv) != 3:
    print sys.argv[0] + ": Invalid number of arguments."
    print "Usage: " + sys.argv[0] + " linecount filename"
    print "to remove linecount lines from the end of the file"
    exit(2)

number = int(sys.argv[1])
file = sys.argv[2]
count = 0

with open(file,'r+b') as f:
    f.seek(0, os.SEEK_END)
    end = f.tell()
    while f.tell() > 0:
        f.seek(-1, os.SEEK_CUR)
        char = f.read(1)
        if char != '\n' and f.tell() == end:
            print "No change: file does not end with a newline"
            exit(1)
        if char == '\n':
            count += 1
        if count == number + 1:
            f.truncate()
            print "Removed " + str(number) + " lines from end of file"
            exit(0)
        f.seek(-1, os.SEEK_CUR)

if count < number + 1:
    print "No change: requested removal would leave empty file"
    exit(3)

Ini adalah versi Python 3:

#!/usr/bin/env python3.0

import os, sys

if len(sys.argv) != 3:
    print(sys.argv[0] + ": Invalid number of arguments.")
    print ("Usage: " + sys.argv[0] + " linecount filename")
    print ("to remove linecount lines from the end of the file")
    exit(2)

number = int(sys.argv[1])
file = sys.argv[2]
count = 0

with open(file,'r+b', buffering=0) as f:
    f.seek(0, os.SEEK_END)
    end = f.tell()
    while f.tell() > 0:
        f.seek(-1, os.SEEK_CUR)
        print(f.tell())
        char = f.read(1)
        if char != b'\n' and f.tell() == end:
            print ("No change: file does not end with a newline")
            exit(1)
        if char == b'\n':
            count += 1
        if count == number + 1:
            f.truncate()
            print ("Removed " + str(number) + " lines from end of file")
            exit(0)
        f.seek(-1, os.SEEK_CUR)

if count < number + 1:
    print("No change: requested removal would leave empty file")
    exit(3)

Ini adalah versi Python 2.4:

#!/usr/bin/env python2.4

import sys

if len(sys.argv) != 3:
    print sys.argv[0] + ": Invalid number of arguments."
    print "Usage: " + sys.argv[0] + " linecount filename"
    print "to remove linecount lines from the end of the file"
    sys.exit(2)

number = int(sys.argv[1])
file = sys.argv[2]
count = 0
SEEK_CUR = 1
SEEK_END = 2

f = open(file,'r+b')
f.seek(0, SEEK_END)
end = f.tell()

while f.tell() > 0:
    f.seek(-1, SEEK_CUR)
    char = f.read(1)
    if char != '\n' and f.tell() == end:
        print "No change: file does not end with a newline"
        f.close()
        sys.exit(1)
    if char == '\n':
        count += 1
    if count == number + 1:
        f.truncate()
        print "Removed " + str(number) + " lines from end of file"
        f.close()
        sys.exit(0)
    f.seek(-1, SEEK_CUR)

if count < number + 1:
    print "No change: requested removal would leave empty file"
    f.close()
    sys.exit(3)

Anda dapat mencoba kepala GNU

head -n -2 file

Saya melihat Debian Squeeze/sistem pengujian saya (tetapi bukan Lenny/stable) menyertakan perintah "truncate" sebagai bagian dari paket "coreutils".

Dengan itu Anda bisa melakukan sesuatu seperti

truncate --size=-160 myfile

untuk menghapus 160 byte dari akhir file (jelas Anda perlu mengetahui dengan tepat berapa banyak karakter yang perlu Anda hapus).


Linux
  1. Bagaimana cara menghapus garis yang muncul pada file B dari file A lainnya?

  2. Hitung baris dalam file besar

  3. Bagaimana saya bisa mendapatkan kata-kata di antara dua contoh teks/pola pertama?

  1. Bagaimana Cara Menghapus Garis Duplikat Di Dalam File Teks?

  2. Hapus Beberapa Baris Pertama Secara Efisien Dari File Teks?

  3. Mengubah urutan baris dalam file

  1. Bagaimana Cara Menghapus Bom Dari File Utf-8?

  2. Cetak Konten File Tanpa Baris Pertama Dan Terakhir?

  3. Ekstrak Teks Antara Dua Baris Tertentu?