2010-08-19 6 views
3

Мне нужно создать выходной текстовый файл, удалив первые две строки входного файла.Быстро удалить первые n строк из многих текстовых файлов

На данный момент я использую СЭД "1,2d" input.txt> output.txt

мне нужно сделать это для тысяч файлов, так что я использую Python:

import os 
for filename in somelist: 
    os.system('sed "1,2d" %s-in.txt > %s-out.txt'%(filename,filename)) 

, но это довольно медленно.

Мне нужно сохранить исходный файл, поэтому я не могу установить его на месте.

Есть ли способ сделать это быстрее? Использование чего-то другого, кроме sed? Возможно, используя какой-то другой язык сценариев, чем python? Стоит ли писать короткую программу на C или файл-запись на диске может быть узким местом?

+0

Один вопрос с помощью os.system() является то, что он запускает новую оболочку каждый цикл что добавляет немного накладных расходов. Запуск непосредственно в петле, например. bash уменьшит накладные расходы немного (но увеличение производительности, вероятно, будет только теоретическим, поскольку дисковый ввод-вывод является ограничивающим фактором, как упоминалось другими) – pafcu

+0

@pafcu: Возможно, это не так теоретически, если файлы были все четыре строки , Я бы предположил, что вы могли бы добиться такого же улучшения, используя 'exec' вместо' system'. Для этого не нужна оболочка. – Cascabel

ответ

9

Используйте tail. Сомнение в том, что все может быть значительно быстрее:

tail -n +3 input.txt > output.txt 

Оберните его в свою петлю выбора. Но я действительно сомневаюсь, что sed на целую тонну медленнее - как вы говорите, дисковый ввод/вывод обычно является конечным узким местом.

+0

Спасибо, я только что попробовал, и это по сути неотличимо от оригинала в том, сколько времени требуется для запуска (точно так же, как sed -i.bak от ghostdog), поэтому я подозреваю, что это узкое место для ввода-вывода. – Samizdis

+0

Я знаю, что я не смогу получить ответ, но ... почему это произошло? Это * * канонический способ выполнить эту операцию в * nix. – Cascabel

3
for file in *.ext 
do 
    sed -i.bak -n '3,$p' $file 
done 

или просто

sed -i.bak -n '3,$p' *.ext 
+0

Это очень приятно, спасибо, но, к сожалению, кажется, что i/o является узким местом. – Samizdis

4

Я думаю, что это будет быстрее, чем запуск СЕПГ:

import os 
import shutil 

path = '/some/path/to/files/' 
for filename in os.listdir(path): 
    basename, ext = os.path.splitext(filename) 
    fullname = os.path.join(path, filename) 
    newname = os.path.join(path, basename + '-out' + ext) 
    with open(fullname) as read: 
     #skip first two lines 
     for n in xrange(2): 
      read.readline() 
     # hand the rest to shutil.copyfileobj 
     with open(newname, 'w') as write: 
      shutil.copyfileobj(read, write) 
Смежные вопросы