извлечь определенный набор строк из файлов - PullRequest
1 голос
/ 19 августа 2010

У меня есть много больших (~ 30 МБ за штуку) текстовых файлов с разделителями табуляции и линиями переменной ширины.Я хочу извлечь 2-е поле из n-й (здесь n = 4) и следующей за последней строки (последняя строка пуста).Я могу получить их отдельно, используя awk:

awk 'NR==4{print $2}' filename.dat

и (я не понимаю это полностью, но)

awk '{y=x "\n" $2};END{print y}' filename.dat

но есть ли способ собрать их в один вызов?Мое более широкое намерение состоит в том, чтобы обернуть его в скрипт Python, чтобы собрать эти значения из большого количества файлов (многие тысячи) в отдельных каталогах, и я хочу уменьшить количество системных вызовов.Огромное спасибо -

Редактировать: Я знаю, что могу прочитать весь файл с помощью Python, чтобы извлечь эти значения, но я подумал, что awk может быть более подходящим для задачи (сиз двух значений, расположенных в конце большого файла).

Ответы [ 4 ]

3 голосов
/ 19 августа 2010
awk 'NR==4{print $2};{y=x "\n" $2};END{print y}' filename.dat
2 голосов
/ 19 августа 2010

Вы можете передать число строк в awk:

awk -v lines=$( wc -l < filename.dat ) -v n=4 '
    NR == n || NR == lines-1 {print $2}
' filename.dat

Обратите внимание, что в команде wc используйте перенаправление <, чтобы избежать печати имени файла.

1 голос
/ 20 августа 2010

Это моё решение в Python. Вдохновленный этот другой код :

def readfields(filename,nfromtop=3,nfrombottom=-2,fieldnum=1,blocksize=4096):
    f = open(filename,'r')
    out = ''
    for i,line in enumerate(f):
        if i==nfromtop:
            out += line.split('\t')[fieldnum]+'\t'
            break
    f.seek(-blocksize,2)
    out += str.split(f.read(blocksize),'\n')[nfrombottom].split('\t')[fieldnum]
    return out

Когда я его профилировал, разница была на 0,09 секунды быстрее, чем решение, вызывающее awk (awk 'NR==4{print $2};{y=x $2};END{print y}' filename.dat) с модулем подпроцесса. Не нарушитель соглашения, но когда остальная часть сценария написана на Python, кажется, что это принесет плоды (тем более что у меня много этих файлов).

1 голос
/ 19 августа 2010

Вот как реализовать это в Python, не читая весь файл

Чтобы получить n-ую строку, у вас нет другого выбора, кроме как прочитать файл до n-й строки, поскольку строки имеют переменную ширину.

Чтобы получить вторую до последней строки, угадайте какова длина строки (быть щедрой) и ищите столько байтов до конца файла.

read() от точки, к которой вы стремились. Подсчитайте количество символов новой строки - вам нужно как минимум два. Если количество строк перевода меньше 2, удвойте свое предположение и попробуйте снова

разделить данные, которые вы читаете на новых строках - строка, которую вы ищите, будет вторым последним элементом в разделении

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...