2013-04-28 5 views
2

Demander des instructions sur l'utilisation de awk pour extraire des blocs de texte avec des lignes spécifiques d'un fichier.awk - comment extraire un motif

Le fichier a la structure suivante:

<Information> 
<CID>_whole_number_A_</CID> 
<string>_text_that_is_not_useful_</string> 
<string>_text_that_is_not_useful_</string> 
<string>_PATTERN_A_</string> 
<string>_text_that_is_not_useful_</string> 
</Information> 
<Information> 
<CID>_whole_number_B_</CID> 
<string>_PATTERN_B_</string> 
<string>_text_that_is_not_useful_</string> 
<string>_text_that_is_not_useful_</string> 
<string>_text_that_is_not_useful_</string> 
<string>_text_that_is_not_useful_</string> 
<string>_text_that_is_not_useful_</string> 
</Information> 

Voudrait awk d'envoyer le modèle suivant dans un nouveau fichier.

<Information> 
<CID>_whole_number_A_</CID> 
<string>_PATTERN_A_</string> 
</Information> 
<Information> 
<CID>_whole_number_B_</CID> 
<string>_PATTERN_B_</string> 
</Information> 

Remarques sur les données:

  • Le fichier a 300,000+ éléments CID; chacun identifié par un numéro entier unique .
  • Les PATTERN (_PATTERN_A_, _PATTERN_B_, etc.) ont le format UNII- < 10 caractères>. Par exemple: UNII-4J4Z8788N8 ou UNII-12L95QD6KV.
  • Tous les CID n'ont pas d'UNII.

Remarques à propos de mon environnement:

  • Am fonctionnant sous Windows 7 et en utilisant les utilitaires GnuWin32

Alors, reformulant en anglais:

dans FILE_1

trouver tous les CID qui ont un UNII

envoyer les résultats filtrés à FILE_2

Merci à l'avance pour obtenir des instructions.

============================================== OK, je fais quelque chose de mal.

Dans ma première mise en œuvre, le programme retourne que « enregistrement commence à » et « balise de fermeture, » i.e. .:

<Information> 
</Information> 

Voici comment j'ai appliqué vos instructions.

D'abord, je suis sous Windows alors changé FS = "\ r \ n"

La première expression régulière est UNII, donc changé/UNII /.

La deuxième expression régulière est CID, que vous avez utilisée dans vos instructions. Je n'ai fait aucun changement là-bas.

Pour la deuxième instance de PATTERN, j'ai changé pour/UNII /.

Voici comment mes substitutions ressemblent:

BEGIN { 
    RS="<Information>" 
    FS="\r\n" 
} 
/UNII/ { 
    print RS 
    for (i=1;i<NF;i++) { 
     if ($i ~ /CID/ || $i ~ /UNII/) { 
      print $i 
     } 
    } 
    print "</Information>" 
} 

Parce que je me sers de Windows, j'utiliser un chemin complet pour exécuter les utilitaires GnuWin32 et lire/écrire des données. Alors mon.le fichier bat ressemble à ceci:

C:\bin\awk -f C:\bin\script.awk <C:\Users\Owner\data\input_file.txt> C:\Users\Owner\data\output_file.txt 

Qu'est-ce que je fais mal?

============================================== =================================== Voici les données échantillon:

<Information> 
    <CID>1</CID> 
    <Synonym>Acetyl carnitine</Synonym> 
    <Synonym>O-Acetyl-L-carnitine</Synonym> 
    <Synonym>Ammonium, (3-carboxy-2-hydroxypropyl)trimethyl-, hydroxide, inner salt, acetate, DL-</Synonym> 
    <Synonym>UNII-07OP6H4V4A</Synonym> 
    <Synonym>_20+_more_</Synonym> 
</Information> 
<Information> 
    <CID>10006</CID> 
    <Synonym>HYDANTOIN</Synonym> 
    <Synonym>UNII-I6208298TA</Synonym> 
    <Synonym>53760_FLUKA</Synonym> 
    <Synonym>NSC9226</Synonym> 
    <Synonym>_20+_more_</Synonym> 
</Information> 
<Information> 
    <CID>10007</CID> 
    <Synonym>Lucofen SA</Synonym> 
    <Synonym>461-78-9</Synonym> 
    <Synonym>EINECS 207-314-9</Synonym> 
    <Synonym>STK664067</Synonym> 
    <Synonym>DEA No. 1645</Synonym> 
    <Synonym>UNII-NHW07912O7</Synonym> 
    <Synonym>CHEMBL1201269</Synonym> 
    <Synonym>HMS1376E21</Synonym> 
    <Synonym>_20+_more_</Synonym> 
</Information> 

Répondre

1

Ce script devrait fournir un bon point de départ:

BEGIN { 
    RS="<Information>" 
    FS="\n" 
} 
/UNII/ { 
    print RS 
    for (i=1;i<NF;i++) { 
     if ($i ~ /CID/ || $i ~ /UNII/) { 
      print $i 
     } 
    } 
    print "</Information>" 
} 

Enregistrement à script.awk et en cours d'exécution sur votre entrée de l'échantillon produit:

$ awk -f script.awk file 
<Information> 
    <CID>1</CID> 
    <Synonym>UNII-07OP6H4V4A</Synonym> 
</Information> 
<Information> 
    <CID>10006</CID> 
    <Synonym>UNII-I6208298TA</Synonym> 
</Information> 
<Information> 
    <CID>10007</CID> 
    <Synonym>UNII-NHW07912O7</Synonym> 
</Information> 
+0

Merci. J'essaierai cela ce matin et je reviendrai à vous si je rencontre des erreurs (d'utilisateur). –

+0

Ajout de questions supplémentaires aux instructions de réponse –

+0

Il est difficile de déboguer sans le fichier d'entrée, essayez de supprimer le script, si seulement un seul '' et '' est vu dans le fichier de sortie, il suggère l'ensemble le fichier est traité comme un enregistrement, c'est-à-dire que le séparateur d'enregistrement '' correspond exactement, vérifiez la casse. –

1

Tout d'abord, awk est complètement le mauvais outil pour cela. Mais la façon la plus simple de le faire avec awk, est de supprimer les lignes que vous ne voulez pas (plutôt que de sélectionner ceux que vous ne voulez):

/Synonym/ && !/UNII/ { next } 
{ print } 
+0

Ceci est une simplification et échouera sur le cas 'Non tous les CID a un UNII.' –

Questions connexes