GNU/Linux >> Znalost Linux >  >> Linux

Efektivně odstraňte poslední dva řádky extrémně velkého textového souboru

Nezkoušel jsem to na velkém souboru, abych zjistil, jak je rychlý, ale mělo by to být poměrně rychlé.

Chcete-li použít skript k odstranění řádků z konce souboru:

./shorten.py 2 large_file.txt

Hledá na konec souboru, zkontroluje, zda je poslední znak nový řádek, pak čte každý znak jeden po druhém zpět, dokud nenajde tři nové řádky a těsně za tímto bodem soubor zkrátí. Změna je provedena na místě.

Upravit: Dole jsem přidal verzi Pythonu 2.4.

Zde je verze pro 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)

Zde je verze Pythonu 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)

Zde je verze Pythonu 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)

můžete zkusit GNU head

head -n -2 file

Vidím, že mé Debian Squeeze/testovací systémy (ale ne Lenny/stable) obsahují příkaz "truncate" jako součást balíčku "coreutils".

S ním můžete jednoduše udělat něco jako

truncate --size=-160 myfile

k odstranění 160 bajtů z konce souboru (samozřejmě musíte přesně zjistit, kolik znaků potřebujete odstranit).


Linux
  1. Výstup společných řádků (podobností) dvou textových souborů (opak rozdílu)?

  2. Jak odstranit Bom ze souboru UTF-8?

  3. Vytisknout obsah souboru bez prvního a posledního řádku?

  1. Jak odstranit řádky, které se objevují v souboru B, z jiného souboru A?

  2. Jak odstranit X bajtů z konce velkého souboru bez přečtení celého souboru?

  3. Počítejte řádky ve velkých souborech

  1. Jak použít sed k odstranění posledních n řádků souboru

  2. Jak mohu získat slova mezi prvními dvěma výskyty textu/vzoru?

  3. Jak extrahovat text z velkého souboru počínaje prvním výskytem řetězce?