GNU/Linux >> Tutoriales Linux >  >> Linux

Elimine eficientemente las dos últimas líneas de un archivo de texto extremadamente grande

No he probado esto en un archivo grande para ver qué tan rápido es, pero debería ser bastante rápido.

Para usar el script para eliminar líneas del final de un archivo:

./shorten.py 2 large_file.txt

Busca hasta el final del archivo, verifica para asegurarse de que el último carácter sea una nueva línea, luego lee cada carácter uno a la vez retrocediendo hasta que encuentra tres nuevas líneas y trunca el archivo justo después de ese punto. El cambio se realiza en su lugar.

Editar: Agregué una versión de Python 2.4 en la parte inferior.

Aquí hay una versión para 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)

Aquí hay una versión de 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)

Aquí hay una versión de 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)

puedes probar cabeza GNU

head -n -2 file

Veo que mis sistemas Debian Squeeze/testing (pero no Lenny/stable) incluyen un comando "truncar" como parte del paquete "coreutils".

Con él podrías simplemente hacer algo como

truncate --size=-160 myfile

para eliminar 160 bytes del final del archivo (obviamente, debe averiguar exactamente cuántos caracteres necesita eliminar).


Linux
  1. Salida de las líneas comunes (similitudes) de dos archivos de texto (el opuesto de diff)?

  2. ¿Cómo quitar el Bom de un archivo Utf-8?

  3. Eliminar líneas vacías en un archivo de texto a través de grep

  4. Contar líneas en archivos grandes

  5. Cómo usar sed para eliminar las últimas n líneas de un archivo

Cómo agregar texto al comienzo del archivo en Linux

5 formas de contar el número de líneas en un archivo

¿El comando Cat no muestra las líneas del texto?

¿Cómo puedo obtener palabras entre las dos primeras instancias de texto/patrón?

¿Cómo extraer texto de un archivo grande, comenzando en la primera aparición de una cadena?

¿Existe una forma rápida de obtener el último archivo en un TAR grande?