Я работаю с очень большим (~11GB) текстовым файлом в системе Linux. Я выполняю его через программу, которая проверяет файл на наличие ошибок. Как только ошибка найдена, я должен или зафиксировать строку или удалить строку полностью. И затем повторитесь...
В конечном счете, как только я доволен процессом, я автоматизирую его полностью. На данный момент однако давайте предположим, что я выполняю это вручную.
Что было бы самым быстрым (с точки зрения времени выполнения) способ удалить определенную строку из этого большого файла? Я думал о выполнении его в Python..., но буду открыт для других примеров. Строка могла бы быть где угодно в файле.
Если Python, примите следующий интерфейс:
def removeLine(filename, lineno):
Спасибо,
- aj
Вы можете иметь два файловых объекта для одного и того же файла одновременно (один для чтения, другой для записи):
def removeLine(filename, lineno):
fro = open(filename, "rb")
current_line = 0
while current_line < lineno:
fro.readline()
current_line += 1
seekpoint = fro.tell()
frw = open(filename, "r+b")
frw.seek(seekpoint, 0)
# read the line we want to discard
fro.readline()
# now move the rest of the lines in the file
# one line back
chars = fro.readline()
while chars:
frw.writelines(chars)
chars = fro.readline()
fro.close()
frw.truncate()
frw.close()
Измените файл на месте , оскорбительная строка заменяется пробелами, поэтому оставшаяся часть файла не требуется перемещаться по диску. Вы также можете « исправить » строку на месте, если длина исправления не превышает длину заменяемой строки
import os
from mmap import mmap
def removeLine(filename, lineno):
f=os.open(filename, os.O_RDWR)
m=mmap(f,0)
p=0
for i in range(lineno-1):
p=m.find('\n',p)+1
q=m.find('\n',p)
m[p:q] = ' '*(q-p)
os.close(f)
Если другую программу можно изменить для вывода смещения файла вместо номера строки, вы можете назначьте смещение для p напрямую и обойдитесь без цикла for
Насколько Я знаю, вы не можете просто открыть текстовый файл с помощью Python и удалить строку. Вы должны создать новый файл и переместить в него все, кроме этой строки. Если вы знаете конкретную строку, вы должны сделать что-то вроде этого:
f = open('in.txt')
fo = open('out.txt','w')
ind = 1
for line in f:
if ind != linenumtoremove:
fo.write(line)
ind += 1
f.close()
fo.close()
Вы, конечно, можете вместо этого проверить содержимое строки, чтобы определить, хотите ли вы ее сохранить или нет. Я также рекомендую, если у вас есть целый список строк, которые нужно удалить / изменить, сделать все эти изменения за один проход через файл.
Если строки имеют переменную длину, я не верю, что есть лучший алгоритм, чем чтение файла построчно и запись всех строк, кроме для тех, которые вам не нужны.
Вы можете идентифицировать эти строки, проверяя некоторые критерии или ведя текущий счет прочитанных строк и подавляя запись строки (строк), которая вам не нужна.
Если строки имеют фиксированную длину и вы хотите удалить определенные номера строк, вы можете использовать seek
для перемещения указателя файла ... Я сомневаюсь, что вам так повезло.
Синтаксические анализаторы C++ трудно построить .
Я не могу говорить с опытом использования C++ грамматик ANTLR. Здесь я обсуждаю то, что я узнал, прочитав заметки, приложенные к той, которую я видел на сайте ANTLR; по существу автор произвёл неполную грамматику. И это было только для C++ 98. Это было некоторое время с тех пор, как я посмотрел; могут быть и другие.
Наш Набор средств обновления программного обеспечения DMS имеет надежный внешний интерфейс C++ .
Лексер обрабатывает все элементы для ANSI, GCC3, MS Visual Studio 2008, включая числа с плавающей точки большой точности и т.д.
[ПРАВКА: 12/2011. Теперь обрабатывает директивы C++ 11 и OpenMP]
[EDIT: 3/2015: Теперь обрабатывает C++ 14 в вариантах GCC и MS. Смотрите некоторые деревья синтаксического анализа здесь на SO ]
Наличие «просто» синтаксического анализатора на самом деле не очень полезно. Над «просто разбором» и за его пределами наш фронтэнд построит АСТ, построит точные таблицы символов (для C++ это сделать крайне сложно), выполнит функционально-локальный анализ потока, позволит осуществить программные преобразования и т. д. См. Жизнь после анализа .
[EDIT: 5/2019: Теперь обрабатывает C++ 17 в вариантах ANSI, GCC и MS. Полное разрешение имен и типов в единицах компиляции. Используется для автоматизации масштабного рефакторинга/разделения класса Бога между системами из 3000 единиц компиляции.]
-121--3199715-Это вполне нормально, но как только вы почувствуете, что контроллер становится слишком загроможденным, вы можете переформатировать его зависимости в агрегированную службу .
-121--2809759-Обновление: решение с использованием sed по запросу плаката в комментарии.
Чтобы удалить, например, вторую строку файла:
sed '2d' input.txt
Используйте переключатель -i
для редактирования на месте. Предупреждение: это разрушительная операция. Сведения об автоматическом создании резервной копии см. в справке по этой команде.
@OP, если вы можете использовать awk, например, предполагая номер строки 10
$ awk 'NR!=10' file > newfile
Я думаю, здесь был задан несколько похожий, если не совсем тот же тип вопроса. Чтение (и запись) построчно выполняется медленно, но вы можете сразу прочитать более крупный кусок в памяти, пройти эту построчно, пропуская строки, которые вам не нужны, а затем записать это как единый фрагмент в новый файл. Повторяйте до тех пор, пока не будете готовы. Наконец, замените исходный файл новым.
Когда вы читаете фрагмент, вам нужно иметь дело с последней, потенциально неполной строкой, которую вы прочитали, и добавить ее к следующему фрагменту, который вы читаете.
def removeLine(filename, lineno):
in = open(filename)
out = open(filename + ".new", "w")
for i, l in enumerate(in, 1):
if i != lineno:
out.write(l)
in.close()
out.close()
os.rename(filename + ".new", filename)