GNU/Linux >> Tutoriels Linux >  >> Linux

Supprimez efficacement les deux dernières lignes d'un fichier texte extrêmement volumineux

Je n'ai pas essayé cela sur un gros fichier pour voir à quelle vitesse il est, mais il devrait être assez rapide.

Pour utiliser le script pour supprimer des lignes à la fin d'un fichier :

./shorten.py 2 large_file.txt

Il cherche jusqu'à la fin du fichier, vérifie que le dernier caractère est une nouvelle ligne, puis lit chaque caractère un à la fois en revenant en arrière jusqu'à ce qu'il trouve trois nouvelles lignes et tronque le fichier juste après ce point. La modification est effectuée sur place.

Modifier : J'ai ajouté une version Python 2.4 en bas.

Voici une version pour 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)

Voici une version 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)

Voici une version 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)

vous pouvez essayer la tête GNU

head -n -2 file

Je vois que mes systèmes Debian Squeeze/testing (mais pas Lenny/stable) incluent une commande "truncate" dans le cadre du paquet "coreutils".

Avec cela, vous pouvez simplement faire quelque chose comme

truncate --size=-160 myfile

pour supprimer 160 octets à partir de la fin du fichier (évidemment, vous devez déterminer exactement combien de caractères vous devez supprimer).


Linux
  1. Supprimer les lignes vides dans un fichier texte via grep

  2. Compter les lignes dans les fichiers volumineux

  3. Comment utiliser sed pour supprimer les n dernières lignes d'un fichier

  4. Supprimer les lignes paires ou impaires d'un fichier texte

  5. Comment puis-je obtenir des mots entre les deux premières instances de texte/motif ?

Comment ajouter du texte au début du fichier sous Linux

5 façons de compter le nombre de lignes dans un fichier

Imprimer le contenu du fichier sans les premières et dernières lignes ?

La commande Cat n'affiche pas les lignes du texte ?

Comment supprimer les lignes qui apparaissent sur le fichier B d'un autre fichier A ?

Comment supprimer X octets à la fin d'un gros fichier sans lire tout le fichier ?