GNU/Linux >> Linux Esercitazione >  >> Linux

Rimuovi in ​​modo efficiente le ultime due righe di un file di testo estremamente grande

Non l'ho provato su un file di grandi dimensioni per vedere quanto è veloce, ma dovrebbe essere abbastanza veloce.

Per utilizzare lo script per rimuovere righe dalla fine di un file:

./shorten.py 2 large_file.txt

Cerca fino alla fine del file, controlla che l'ultimo carattere sia una nuova riga, quindi legge ogni carattere uno alla volta andando indietro finché non trova tre nuove righe e tronca il file subito dopo quel punto. La modifica viene effettuata sul posto.

Modifica: Ho aggiunto una versione Python 2.4 in fondo.

Ecco una versione per 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)

Ecco una versione di 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)

Ecco una versione di 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)

puoi provare GNU head

head -n -2 file

Vedo che i miei sistemi Debian Squeeze/testing (ma non Lenny/stable) includono un comando "truncate" come parte del pacchetto "coreutils".

Con esso potresti semplicemente fare qualcosa come

truncate --size=-160 myfile

per rimuovere 160 byte dalla fine del file (ovviamente devi capire esattamente quanti caratteri devi rimuovere).


Linux
  1. Come rimuovere le righe duplicate all'interno di un file di testo?

  2. Rimuovere in modo efficiente le prime due righe da un file di testo?

  3. Stampa il contenuto del file senza la prima e l'ultima riga?

  4. Estrarre il testo tra due righe specifiche?

  5. Come rimuovere le linee che appaiono sul file B da un altro file A?

Come aggiungere testo all'inizio del file in Linux

5 modi per contare il numero di righe in un file

Il comando Cat non mostra le righe del testo?

Come rimuovere X byte dalla fine di un file di grandi dimensioni senza leggere l'intero file?

Rimuovi le righe pari o dispari da un file di testo

Modificare l'ordine delle righe in un file