2010-03-16 2 views
0

J'ai un énorme fichier texte qui suit la structure:sous-structure Extrait d'un fichier texte en utilisant bash ou python

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

Je voudrais extraire un TAG spécifique, (c.-à-TAG54) sa personne « sous-structure », ce qui serait

SET 
TAG54 
... 
... 
SET 

Chaque sous-structure, pour une donnée TAG_i contient toujours:

première ligne: SET deuxième ligne: TAG_i (dans ce cas TAG54) un nombre arbitraire de lignes dernière ligne: SET

Je me demande quelle serait la meilleure façon de le faire, que ce soit en bash ou python, donc pour un TAG donné, on peut « extraire » cette sous-structure.

Merci

+0

Pas une très bonne solution, mais vous pouvez utiliser un mon mauvais regex en python: /TAG\d+?(.+?)SET/gsm Il y a une meilleure façon de faire des sauts de ligne, mais le regex l'outil que j'utilisais ne les aime pas. – Davis

Répondre

1

Voici une approche Python: vous passez dans le fichier ouvert comme premier argument, le numéro d'étiquette comme second argument, et de revenir à la suite d'une liste des lignes concernées (y compris les caractères de saut de ligne) ou une ligne vide si l'étiquette n'est pas trouvée dans le fichier:

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 

Ceci devrait être raisonnablement performant. Si vous voulez d'autres formes d'arguments et/ou de résultats, il ne devrait pas être difficile de les modifier en conséquence, bien sûr.

0

Si votre système prend en charge de grep-P pour perl regexp:

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

salut, ça ne marche pas. pouvez-vous me dire ce que chaque partie fait? merci beaucoup – flow

+0

'grep' est un outil de recherche; l'option '-P' fait que' grep' utilise une expression rationnelle de type perl (votre système peut ne pas supporter '-P'); ''SET \ nTAG54 \ n [. \ N] * \ nSET'' est l'expression rationnelle devant correspondre:' SET' suivi d'une nouvelle ligne, suivi de 'TAG54' et d'une nouvelle ligne, puis d'un nombre arbitraire (' * ') caractères arbitraires et/ou newlines ('[. \ n]'), une nouvelle ligne, et 'SET'; 'file.txt' est le nom du fichier à rechercher. – Isaac

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

gawk:

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 

si vous le faites avec les scripts shell, passez votre variable shell awk en utilisant -v. par exemple

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

salut, votre approche est vraiment sympa et simple! J'ai oublié de mentionner que j'ai aussi besoin des lignes avec "SET" au début et à la fin du fichier, mais je le ferai par moi-même. Merci – flow

Questions connexes