1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2017
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2017
    Messages : 19
    Points : 5
    Points
    5

    Par défaut Parcourir les motifs dans un fichier A et les supprimer dans le fichier B

    Bonjour à vous,

    Je rencontre une petite difficulté dans un script. J'ai un premier fichier qui contient des motifs à supprimer dans un fichier B, voici mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while read line; do sed -e 's/'"${line}"'[ACGT]*//g' fichierB.txt > test;done < fichierA.txt
    Je n'arrive à supprimer qu'un motif parmi ma liste (la dernière).
    Quelqu'un aurait une idée et pourrait m'expliquer pourquoi ce script ne fonctionne pas pour toutes les mutations mais seulement pour une ?
    De plus, tous les motifs ne sont pas forcément présent.

    Merci pour votre aide
    Fichiers attachés Fichiers attachés

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Ingénieur d'études décisionnel
    Inscrit en
    mai 2002
    Messages
    7 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur d'études décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : mai 2002
    Messages : 7 442
    Points : 22 555
    Points
    22 555

    Par défaut

    La cause du problème : à chaque boucle tu relis le fichier B, non modifié, et tu enregistres les modifications dans un nouveau fichier nommé test, qui sera écrasé à la boucle suivante.
    La solution : renommer à chaque boucle le fichier test en fichier B ou utiliser l'option -i de sed.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2017
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2017
    Messages : 19
    Points : 5
    Points
    5

    Par défaut

    carrément juste avec sed -i ca devrait fonctionner...merci (à force d'avoir la tête dessu...)

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2017
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2017
    Messages : 19
    Points : 5
    Points
    5

    Par défaut

    Désolé mais au final la solution me crée un nouveau problème pour la commande sed:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -e 's/'"${line}"'[ACGT]*//g'
    ici l'idée de cette commande est de supprimer les motifs ${line} suivant potentiellement à la fin, la ou les lettres A ou C ou G ou T répétées de 0 à n fois. Mais cette commande supprime tous les motifs ayant la valeur de ${line}.
    je m'explique: si une valeur de ${line} est 302 la commande va supprimer par exemple 302T. Pour ça c'est ok mais elle va aussi supprimer 16302C pour afficher à la place 16. Là c'est mois cool...

    j'ai essayé cette commande:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -e 's/'"${line}"'[ACGT]*\>//g'
    mais ça ne marche pas....

    Si quelqu'un a une idée? merci beaucoup

  5. #5
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Ingénieur d'études décisionnel
    Inscrit en
    mai 2002
    Messages
    7 442
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur d'études décisionnel
    Secteur : Conseil

    Informations forums :
    Inscription : mai 2002
    Messages : 7 442
    Points : 22 555
    Points
    22 555

    Par défaut

    Il faut commencer par identifier les motifs qui précédent la chaine à supprimer.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  6. #6
    Expert éminent Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    décembre 2012
    Messages
    2 427
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : décembre 2012
    Messages : 2 427
    Points : 6 747
    Points
    6 747

    Par défaut

    Bonjour,

    Une autre solution, tu fabriques une suite de commande sed en traitant tout le fichierA puis tu l'utilises pour le fichierB:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed 's:.*:s/&[ACGT]*//g:' fichierA.txt | sed -f - fichierB.txt
    Par contre, il faut que tu fasses un tri de position des pattern de ton fichierA, car si tu l'utilises tel quel, tu vas rencontrer le souci suivant:
    par exemple d'abord traiter 309.1 et ensuite 309 car si tu supprimes d'abord 309, sed ne trouvera jamais 309.1
    Cordialement.

  7. #7
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    avril 2008
    Messages
    1 657
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : avril 2008
    Messages : 1 657
    Points : 4 376
    Points
    4 376

    Par défaut

    Citation Envoyé par Piotree Voir le message
    Désolé mais au final la solution me crée un nouveau problème pour la commande sed:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -e 's/'"${line}"'[ACGT]*//g'
    Attention! Le texte du code doit être entre les balises [ C O D E ] et [ / C O D E ] (sans les espaces).

    Personnellement, j'écrirais plutôt avec des guillemets:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -e "s/${line}[ACGT]*//g"

    ici l'idée de cette commande est de supprimer les motifs ${line} suivant potentiellement à la fin, la ou les lettres A ou C ou G ou T répétées de 0 à n fois.
    J'imagine que tu veux dire "supprimer les motifs ${line} suivis potentiellement à la fin, par la ou les lettres A ou C ou G ou T répétées de 0 à n fois.", non?

    Mais attention! Est-ce vraiment ce que tu veux?

    Un exemple: si la valeur de ${line} est 302, alors la ligne "302999TGCA" contient bien "302[ACGT]*"!!!
    En effet, 302 est suivi de 0 occurrences de ACG ou T, vu qu'il est suivi d'un 9!!!

    De même, il va aussi trouver la ligne "888302TGCA" ou même la ligne "888302999GTCC".

    En bref, toutes les lignes contenant "302"...

    Mais cette commande supprime tous les motifs ayant la valeur de ${line}.
    Normal (voir ci-dessus).

    je m'explique: si une valeur de ${line} est 302 la commande va supprimer par exemple 302T. Pour ça c'est ok mais elle va aussi supprimer 16302C pour afficher à la place 16. Là c'est mois cool...
    Ce qui serait cool, ce serait que tu nous dises ce que tu veux!

    Tu veux supprimer toute la ligne "16302[ACGT]*" et ne pas garder "16"?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -e "s/.*${line}[ACGT]*//g"
    Tu veux conserver la ligne parce qu'elle commence par 16302 et non par 302?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -e "s/^${line}[ACGT]*//g"
    Quid des lignes "302999TGCA"?

    Si tu veux les conserver, c'est-à-dire si tu veux supprimer les lignes contenant "302", suivie d'au moins une occurrence de ACG ou T, alors il faut remplacer [ACGT]* par [ACGT][ACGT]* (ou une autre syntaxe (plus ou moins portable... suivant la version de "sed")).

  8. #8
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2017
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2017
    Messages : 19
    Points : 5
    Points
    5

    Par défaut

    Merci à tous pour vos commentaires et suggestions...

    jack-ft je veux supprimer tous les motifs du fichierA présent dans le fichierB mais pas les lignes contenant les motifs seulement les motifs. Dans le fichierA la présence des motifs sans lettres (ACGT) signifie que si on trouve un de ces motifs dans le fichierB il sera au moins suivi d'une de ces lettres ou plus.
    EX dans fichierA on a 302 et dans fichierB on a 302AC mais j'ai d'autres fichiers ou on a 302T. Je veux seulement les supprimer.

    Encore merci

  9. #9
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    mars 2004
    Messages
    2 196
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mars 2004
    Messages : 2 196
    Points : 4 479
    Points
    4 479

    Par défaut

    Ce que dit jack-ft c'est que si ton motif occupera toujours une ligne entière, du style :Alors tu peux tout simplement préfixer par "^" : sed -e "s/^${line}[ACGT]*//g" qui assurera que ton matching commence au début de la ligne.

    Si par contre tu peux avoir plusieurs motifs sur une même ligne : 16302C 302T 5302T, tu ne peux pas utiliser ça.
    Dans ce cas-là tu peux passer par la détection de word-boundaries (même si je ne connais pas vraiment leur mode de fonctionnement dans sed, j'aime pas sed) : sed -e "s/\b${line}[ACGT]*//g" (il faudra peut-être échapper le \, donc écrire \\b vu qu'il y a des guillemets, je sais pas trop comment fonctionne l'extrapolation du shell dans ce cas).

  10. #10
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2017
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2017
    Messages : 19
    Points : 5
    Points
    5

    Par défaut

    Merci beaucoup loceka le word-boundaries, ça semble marcher parfaitement. Tu utilises quoi comme alternative à sed?
    Encore merci à tous pour votre aide et à bientôt.

  11. #11
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    novembre 2010
    Messages
    2 275
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : novembre 2010
    Messages : 2 275
    Points : 6 091
    Points
    6 091

    Par défaut

    salut,

    personne n'a encore fait chauffer awk, je me lance :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    awk 'NR==FNR{p=p"|\\y"$1"[ACTG]+\\y";next} {gsub(substr(p,2),"",$0);print}' fichierA.txt fichierB.txt
    et l'output (à vérifier svp ?) sur la base des fichiers donnés dans le premier post :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    indiv80a        73G 263G   458T 709A 750G 930A 1438G 1709A TITI 4216C 4769G 4917G 5147A 7028T 8697A 8860G 9300A 10031C 10463C 11251G 11533T 11719A 11812G 12007A 13368A 14233G 14766T 14905A 15326G 15452A 15607G 15928A 16126C 16294T 16296T 16519C 16183C
    indiv80b        152C 263G   750G 1438G 4047C 4769G 6776C 8860G 16287T 16519C 4769G 4917G 5147A 7028T 8697A 8860G 9300A
    Avant donc que d'écrire, apprenez à penser.
    Selon que notre idée est plus ou moins obscure, l'expression la suit, ou moins nette, ou plus pure.
    Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément.
                                                        - Nicolas Boileau, L'Art poétique

  12. #12
    Expert éminent Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    décembre 2012
    Messages
    2 427
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : décembre 2012
    Messages : 2 427
    Points : 6 747
    Points
    6 747

    Par défaut

    Hello Bufferbob, je ne remets pas en cause ton awk, mais la dernière ligne du "fichierA.txt" est "73G" et dans ton output, il apparait...

    Après, c'est peut-être ce qu'il veut car perso, j'ai pas trop compris son besoin.
    Cordialement.

  13. #13
    Expert confirmé
    Avatar de Loceka
    Profil pro
    Inscrit en
    mars 2004
    Messages
    2 196
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : mars 2004
    Messages : 2 196
    Points : 4 479
    Points
    4 479

    Par défaut

    Citation Envoyé par Piotree Voir le message
    Tu utilises quoi comme alternative à sed?
    J'utilise Perl dont les regex sont un peu plus simples que celles de sed sans switch d'activé (on peut plus ou moins avoir des regex perl-like dans sed).

  14. #14
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    novembre 2010
    Messages
    2 275
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : novembre 2010
    Messages : 2 275
    Points : 6 091
    Points
    6 091

    Par défaut

    Citation Envoyé par disedorgue Voir le message
    la dernière ligne du "fichierA.txt" est "73G" et dans ton output, il apparait...
    yep, en fait il dit plus haut :

    Citation Envoyé par Piotree Voir le message
    Dans le fichierA la présence des motifs sans lettres (ACGT) signifie que si on trouve un de ces motifs dans le fichierB il sera au moins suivi d'une de ces lettres ou plus.
    donc ce que je comprends c'est qu'on ne devrait pas trouver 73G dans le fichierA mais seulement 73 ou alors admettre que le motif est suivi de zéro lettre [ACTG] ou plus (donc au pire il suffit de modifier le [ACTG]+ par [ACTG]*)

    bon c'est peut-être une confusion qui n'a pas lieu d'être, je sais pas trop... l'énoncé est pas hyper formel, c'est pour ça que je demandais une vérification de l'output pour lever toute ambiguïté sur ce qu'on attend précisément
    Avant donc que d'écrire, apprenez à penser.
    Selon que notre idée est plus ou moins obscure, l'expression la suit, ou moins nette, ou plus pure.
    Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément.
                                                        - Nicolas Boileau, L'Art poétique

  15. #15
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2017
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2017
    Messages : 19
    Points : 5
    Points
    5

    Par défaut

    Bonjour et désolé pour ma réponse tardive...
    Pour lever toute ambiguïté, l'idée est de supprimer les motifs du fichier A présents dans le fichier B.
    J'aurai une autre question: comment feriez-vous pour remplacer des motifs:

    par exemple, si on trouve ce motif ACCCC8271A TCTACC8277T dans un fichier et que l'on souhaite le remplacer par celui-ci 8281d 8282d 8283d 8284d 8285d 8286d 8287d 8288d 8289d : Je dois faire ça pour une liste de motifs sur plusieurs fichiers. En python j'aurais peut-être utilisé les dictionnaires mais en bash j'en ai aucune idée, en auriez-vous une?

    Merci encore pour votre aide.

  16. #16
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    novembre 2010
    Messages
    2 275
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : novembre 2010
    Messages : 2 275
    Points : 6 091
    Points
    6 091

    Par défaut

    Citation Envoyé par Piotree Voir le message
    Pour lever toute ambiguïté, l'idée est de supprimer les motifs du fichier A présents dans le fichier B.
    je pense que ce point là ne présentait plus vraiment d’ambiguïté en fait

    J'aurai une autre question: comment feriez-vous pour remplacer des motifs
    sed semble encore une fois très adapté à l'exercice, on peut même lui donner le fichier en entrée directement possiblement, à voir selon le format etc.
    n'hésite pas à revenir nous dire si tu bloques malgré tes essais
    Avant donc que d'écrire, apprenez à penser.
    Selon que notre idée est plus ou moins obscure, l'expression la suit, ou moins nette, ou plus pure.
    Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément.
                                                        - Nicolas Boileau, L'Art poétique

  17. #17
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    octobre 2017
    Messages
    19
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Charente (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : octobre 2017
    Messages : 19
    Points : 5
    Points
    5

    Par défaut

    Salut BufferBob,

    Aurais-tu un point de départ pour spécifier le motifs à échanger par exemple:

    valeur de départ = Valeur d'arrivée
    A567ACCCC = 573.1C 573.2C 573.3C 573.4C
    A16305T = 16305t

    Ainsi si dans mon fichier échantillons tu rencontres ce motif A567ACCCC il doit être changé par 573.1C 573.2C 573.3C 573.4C, ce motif A16305T doit être changé par 16305t et ainsi de suite.....j'ai essayé ce code


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while read i;do while read j;do sed -i "s/$i/$j/g" mutat_list_nom_original_test.txt;done < valeurArrive ; done < valeurDepart
    Il me change toujours la même mutation (je comprends pourquoi) mais je ne vois pas comment spécifier que ce motif doit être modifié par celui là et tel autre par tel autre...?

    Si besoin je peux fournir des fichiers mais j'imagine que ce pas très compliqué pour vous.
    Merci par avance

  18. #18
    Expert éminent Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    décembre 2012
    Messages
    2 427
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : décembre 2012
    Messages : 2 427
    Points : 6 747
    Points
    6 747

    Par défaut

    Soit tu crée directement un script sed qui ressemblera à:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    s/oldval1/newval1/g
    s/oldval2/newval2/g
    ...
    ...
    ensuite tu n'auras plus qu'à lancer la commande:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    sed -f script.sed fichier_a_traiter
    Ou bien tu fabriques le dit fichier sed à la volée comme déjà montré dans mon premier post.

    Mais comme déjà expliqué précédemment, ce genre de script, traite la ligne du fichier en cours avec chaque regexp, et donc si on a par exemple une ligne qui ressemble à:
    et que l'on veuille remplacer toto par tata et tata par titi, si on conserve cet ordre, on aura le script sed suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    s/toto/tata/g
    s/tata/titi/g
    et au final, la ligne ressemblera à:
    Alors que si on avait eu le script sed suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    s/tata/titi/g
    s/toto/tata/g
    on aurait obtenu la ligne suivante:
    Donc l'ordre est important, comme pour ton premier problème...
    Cordialement.

Discussions similaires

  1. Réponses: 0
    Dernier message: 24/11/2016, 21h16
  2. Supprimer n lignes d'un fichier.txt et les renvoyer dans un autre fichier
    Par supcomingenieur dans le forum Shell et commandes GNU
    Réponses: 64
    Dernier message: 30/04/2013, 14h59
  3. Réponses: 4
    Dernier message: 06/06/2011, 22h05
  4. Réponses: 5
    Dernier message: 21/02/2007, 17h12
  5. Réponses: 1
    Dernier message: 05/09/2006, 18h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo