Recherche avec grep

Résolu
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. Modérateur
    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
    1. 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
      1. Contributeur
        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
        1. Bonjour Dubcek,

          effectivement, ca fonctionne aussi, merci beaucoup.
          Merci à tous les deux pour votre aide.
          0
          1. Contributeur
            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