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

  • Votes
  • Date
  • Date décroissante
  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. 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. 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.
        1. Bonjour Dubcek,

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