2010-03-16 4 views
0

У меня есть огромный текстовый файл, который следует за структуру:Извлечение подструктуры из текстового файла с помощью Баша или питона

SET 
TAG1 
... 
... 
SET 
... 
SET 
TAG2 
... 
... 
SET 
... 
... 

Я хотел бы извлечь для конкретного TAG (т.е. TAG54) его личности «подструктура », который был бы

SET 
TAG54 
... 
... 
SET 

Каждая подструктура, для данного TAG_i содержит всегда:

Первая строка: SET вторую строку: TAG_i (в данном случае TAG54) произвольное количество строк последней строки: SET

Интересно, что было бы лучшим способом сделать это, будь то в Баш или питона, поэтому для данного TAG, можно «извлечь» эту подструктуру.

Благодаря

+0

Не очень хорошее решение, но вы можете использовать мое плохое регулярное выражение в Python: /TAG\d+?(.+?)SET/gsm Существует лучший способ сделать переводы строк, но регулярное выражение Инструмент, который я использовал, им не нравится. – Davis

ответ

1

Вот Python подход: вы передаете в открытой ручке файла в качестве первого аргумента, число тегов в качестве второго аргумента, и получить обратно в результате список соответствующих строк (включая символы новой строки) , или пустую строку, если тег не найден в файле:

def lookfor(f, tagnum): 
    tag = 'TAG%s\n' % tagnum 
    for line in f: 
    if line == tag: 
     break 
    else: # file finished, tag not found 
    return [] 
    result = ['SET\n', tag] 
    for line in f: 
    result.append(line) 
    if line == 'SET\n': 
     break 
    return result 

Это должно быть достаточно эффективным. Если вам нужны другие формы аргументов и/или результаты, то, конечно же, не сложно их настроить.

0

Если системы grep поддерживает -P для PERL регулярных выражений:

grep -P 'SET\nTAG54\n[.\n]*\nSET' file.txt 
+0

привет, он не работает. можете ли вы сказать мне, что делает каждая часть? Большое спасибо – flow

+0

'grep' - инструмент поиска; параметр '-P' делает' grep' использование regexp perl-типа (ваша система может не поддерживать '-P'); '' SET \ nTAG54 \ n [. \ N] * \ nSET'' - это регулярное выражение, которое должно соответствовать: 'SET', за которым следует новая строка, а затем' TAG54' и новая строка, затем некоторое произвольное число ('*') произвольные символы и/или символы новой строки ('[. \ n]'), новая строка и 'SET'; 'file.txt' - это имя файла для поиска. – Isaac

0
csplit -f tags input.txt '%^TAG54$%-1' '/^SET$/+1' '%.*%' '{*}' 
0

простак:

BEGIN { 
    state=0 
} 

state==0 && $0=="TAG54" { 
    print "SET" 
    state=1 
} 

state==1 { 
    print 
} 

state==1 && $0=="SET" { 
    exit 
} 
0
$ awk -vRS="SET" '/TAG54/{print RT$0RT}' file 
SET 
TAG54 
... 
... 
SET 

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

#!/bin/bash 
read -r -p "what's your tag? " tag 
awk -vRS="SET" -vt="$tag" '$0~tag{print RT$0RT}' file 
+0

привет, ваш подход действительно хороший и простой! Я забыл упомянуть, что мне также нужны строки с «SET» в начале и в конце файла, но я буду делать сам. благодаря – flow

Смежные вопросы