Recherche avec grep

Résolu
Bernard -  
dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   -
Bonjour,

Je voudrais rechercher une chaîne de caractère précise dans un fichier
data.txt
.

Voici ce que j'ai. Le fichier
data.txt
contient une ligne de caractères ;
ACGGGACAGTGGTGACGCGGATCGACT


Je dois trouver ceci :
CGGGACAGTG
GGGACAGTGG
TGGTGACGCG
CGGATCGACT


J'ai essayé avec
grep -o -e ".GG......." data.txt
, ça ne me donne pas le résultat voulu.

CGGGACAGTG
CGGATCGACT

5 réponses

  1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 942
     
    Bonjour,

    Effectivement, il manque deux lignes car
    grep
    cherche de manière gloutonne, et les deux lignes manquantes sont recouvertes par les deux lignes affichées par
    grep
    . Je n'ai pas vu d'option dans grep qui permettent de changer ce comportement mais tu peux vérifier dans
    man grep
    .

    Le problème que tu soulèves est traité dans cette discussion avec d'autres outils comme
    awk
    ou
    python
    .

    Ton problème ne nécessite pas d'expression rationnelle, donc on peut s'en sortir en énumérant tous les slices de 10 caractères tels que le 2nd et le 3ème caractères sont
    GG
    , ce qui donne :

    data.txt

    ACGGGACAGTGGTGACGCGGATCGACT


    toto.py

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    import sys     
    
    def find_occurrences(s):
        return (
            s[i:i+10]
            for i in range(len(s))
            if s[i:i+10][1:3] == "GG"
        )
    
    with open(sys.argv[1]) as f:
        for line in f.readlines(): 
            line = line.strip()
            print("\n".join(
                occurence
                for occurence in find_occurrences(line)
            ))


    Quelques explications :
    • en Python,
      s[i:j]
      la sous-chaîne de
      s
      allant de l'index
      i
      (inclu) à l'index
      j
      (exclu) (on parle de slicing) ;
    • s[i:i+10]
      permet donc d'extraire les 10 caractères glissants de
      s
      en partant de l'index
      i
      ;
    • par rapport à ton critère de filtrage, on veut contrôler le second et le troisième caractères sont "GG", et comme les caractères sont indexés à partir de 0, cela correspond au slice
      [1:3]
      , soit au final
      s[i:i+10][1:3]
      ;
    • la fonction
      find_occurrences
      retourne un itérateur sur une chaîne
      s
      arbitraire (en l'occurrence,
      ACGGGACAGTGGTGACGCGGATCGACT
      ) de sorte à extraire les slices de taille 10 dont second et le troisième caractères sont "GG" ;
    • cette fonction est appelée pour chaque ligne du fichier
      data.txt
      (le chemin vers le fichier est récupéré en paramètre du programme via
      sys.argv[1]
      ) ; les résultats sont concaténés par le caractère
      "\n"
      (retour à la ligne) de sorte à afficher un résultat par ligne ;
    • si tu n'es pas familier de Python et un peu surpris par la position des
      for
      ), c'est parce qu'on utilise un concept propre à python (voir les listes de compréhensions).


    Résultat

    (mando@silk) (~) $ python3 toto.py data.txt
    CGGGACAGTG
    GGGACAGTGG
    TGGTGACGCG
    CGGATCGACT


    Bonne chance
    1
  2. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 660
     
    hello
    $ awk -F ""  '{for (x=1; x<=NF; x++)if ($x=="G" && $(x+1)=="G"){printf $(x-1)$x; for (n=1;n<9;n++)printf $(x+n); print ""}}' data.txt
    CGGGACAGTG
    GGGACAGTGG
    TGGTGACGCG
    CGGATCGACT
    1
  3. Bernard
     
    Bonjour Mamiemando,

    Merci pour ta réponse rapide, j'ai effectivement regardé dans le
    man
    de
    grep
    , je n'ai rien trouvé. J'ai essayé avec
    awk
    combiné avec
    sed
    rien non plus. je vais essayer ton script en python et reviens vers toi.
    0
  4. Bernard
     
    Bonjour Dubcek,

    effectivement, ca fonctionne aussi, merci beaucoup.
    Merci à tous les deux pour votre aide.
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 660
     
    plus court
    $ awk '{for (x=1; x<=length(); x++)if (substr($0, x, 2)=="GG")print substr($0, x-1, 10)}' data.txt
    CGGGACAGTG
    GGGACAGTGG
    TGGTGACGCG
    CGGATCGACT
    0