Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 23/09/2014, à 15:23

jibbah

script bash pour compiler deux fichiers

Bonjour,

Biologiste débutant en langage de programmation bash, j'ai essayé d'écrire un petit script pour tenter de compiler mes séquences fasta pour chaque espèce. Mon arborescence se présente un peu comme cela:

GAPDH/
          Crambus_uliginosellus_GAPDH.fas
          Eudonia_truncicolella_GAPDH.fas
          ...
IDH/
          Crambus_uliginosellus_IDH.fas
          Eudonia_truncicolella_IDH.fas
          ...

J'aimerais donc compiler un fichier de type espece1_gene1.fas avec espece1_gene2.fas dans un troisième fichier que j'aimerais nommer espece1_gene1_gene2.fas, et cela pour le nombre d'espèces présentes. Voilà le script que j'ai écrit, j'obtiens un premier message d'erreur pour la fonction cat, et bien d'autres erreurs doivent suivre.

#!/bin/bash
# compil together the desired number of genes from individual gene files
echo -n "Enter the name of the first gene: "
read gene1
echo -n "Enter the path to the folder containing the samples of the first gene: "
read pathgene1
echo -n "Enter the name of the second gene to be appended: "
read gene2
echo -n "Enter the path to the folder containing the samples of the second gene: "
read pathgene2
for file in $pathgene1*$gene1.fas; 
	cat $file | cut -d "_" -f2 > species
	# extract the name of the species of $file
	cp $file $species_$gene1_$gene2_compil	
	# copy the file to a new file with the two genes concatenated
	find $pathgene2 -name "$species_$gene2*" -print0 | tail -n +2 >> $species_$gene1_$gene2_compil
	# find the gene2 for the species in the second folder, extract the gene sequences (without the header) and paste it to the new file
done 
exit

Merci pour votre aide !

Dernière modification par jibbah (Le 18/09/2017, à 10:56)

Hors ligne

#2 Le 23/09/2014, à 16:07

pinguinman

Re : script bash pour compiler deux fichiers

il manque le "do" après le for.

for file in $pathgene1*$gene1.fas
do
    ###tes instructions###
done


OS : Ubuntu 14.04 / Debian Weezy / Ubuntu server 12.04

Avec Linux t'as un noyau, avec windows t'as des pépins ;)

Hors ligne

#3 Le 23/09/2014, à 16:11

pinguinman

Re : script bash pour compiler deux fichiers

quand tu saisis $pathgene1 tu mets bien le "/" final ?


OS : Ubuntu 14.04 / Debian Weezy / Ubuntu server 12.04

Avec Linux t'as un noyau, avec windows t'as des pépins ;)

Hors ligne

#4 Le 23/09/2014, à 16:28

pinguinman

Re : script bash pour compiler deux fichiers

Il ya un probleme dans ton algorythme.

tu n'as pas créé de variable species, donc $species_$gene2* ne peut pas fonctionner

tu dois créer ta variable :
species=`cat $file | cut -d "_" -f2`

Dernière modification par pinguinman (Le 23/09/2014, à 16:29)


OS : Ubuntu 14.04 / Debian Weezy / Ubuntu server 12.04

Avec Linux t'as un noyau, avec windows t'as des pépins ;)

Hors ligne

#5 Le 23/09/2014, à 16:55

jibbah

Re : script bash pour compiler deux fichiers

Salut Pinguinman,

Merci pour ta réponse. J'ai réécrit le script de manière plus simple pour tester dans un premier temps. Les fichiers avec les séquences se présentent ainsi:
Eudonia_truncicolella>
ATGTTTCGTCTTCAATCTAGT...

Voici le script:

#!/bin/bash
# compil together GAPDH and IDH from their respective folders GAPDH/ and IDH/
for file in GAPDH/*.fas; 
	do
	species=`cat $file | cut -d ">" -f2`
	# extract the name of the species of $file
	cp $file $species_GAPDH_IDH_compil.fas	
	# copy the file to the file where GAPDH and IDH will be concatenated
	find IDH/ -name "$species_IDH*" -print0 | tail -n +2 >> $species_GAPDH_IDH_compil.fas ;
	# search the folder IDH/ for the sequence of the species, extract the gene sequences and paste it to the concatenated file
done 
exit

Il tourne mais la boucle ne semble pas marcher, étant donné que je n'obtiens pas d'output.

Merci pour ton aide.

Dernière modification par jibbah (Le 18/09/2017, à 10:56)

Hors ligne

#6 Le 23/09/2014, à 17:06

pinguinman

Re : script bash pour compiler deux fichiers

j'ai l'impression qu'il n'y a par espece qu'un fichier GAPDH et un fichier IDH, correct ?


OS : Ubuntu 14.04 / Debian Weezy / Ubuntu server 12.04

Avec Linux t'as un noyau, avec windows t'as des pépins ;)

Hors ligne

#7 Le 23/09/2014, à 17:12

pinguinman

Re : script bash pour compiler deux fichiers

Autre chose ton cut revoie le second field (-f2) soit le retour chariot après le >
change -f2 en -f1 pour obtenir ta species.

Enfin, mais c'est esthétique, le exit final est inutile ainsi que les ";" en fin de ligne (";" sert à écrire les commandes à la suite sans retour chariot, bien utile si tu veux exécuter tes commandes directement dans ton shell).

Dernière modification par pinguinman (Le 23/09/2014, à 17:56)


OS : Ubuntu 14.04 / Debian Weezy / Ubuntu server 12.04

Avec Linux t'as un noyau, avec windows t'as des pépins ;)

Hors ligne

#8 Le 23/09/2014, à 17:36

jibbah

Re : script bash pour compiler deux fichiers

J'ai par espèce en effet qu'un fichier GAPDH et IDH par espèce (qu'une seule séquence génique par espèce), mais j'ai trois espèces en tout. La boucle que j'aimerais faire devrait prendre le premier fichier dans GAPDH/ (correspondant à la première espèce), chercher la séquence IDH dans le dossier IDH/ en utilisant la valeur prise par la variable "species" et extraire et coller la séquence IDH à la suite de la séquence GAPDH dans un nouveau fichier.

Hors ligne

#9 Le 23/09/2014, à 17:58

pinguinman

Re : script bash pour compiler deux fichiers

Tu peux donc changer le

find IDH/ -name "$species_IDH*" -print0 | tail -n +2 >> $species_GAPDH_IDH_compil.fas

en

cat IDH/$species_IDH.fas | tail -n +2 >> $species_GAPDH_IDH_compil.fas


OS : Ubuntu 14.04 / Debian Weezy / Ubuntu server 12.04

Avec Linux t'as un noyau, avec windows t'as des pépins ;)

Hors ligne

#10 Le 23/09/2014, à 18:06

pingouinux

Re : script bash pour compiler deux fichiers

Bonjour,
Ceci conviendrait-il ? Sinon tu devrais donner un petit exemple.

#!/bin/bash
for file in GAPDH/*.fas
do
    species=${file%_*}
    species=${species#*/}
    if [ -f IDH/"${species}"_IDH.fas ]; then
       cat "$file" IDH/"${species}"_IDH.fas >"${species}"_GAPDH_IDH_compil.fas
    else
       echo "IDH/${species}_IDH.fas non trouvé"
    fi
done

Édité : Ajout de " + Correction

Dernière modification par pingouinux (Le 23/09/2014, à 18:22)

Hors ligne

#11 Le 23/09/2014, à 18:06

pinguinman

Re : script bash pour compiler deux fichiers

Ah encore un détail, ne dits pas compiler mais concaténer, la compilation consistant à transformer du code source en binaire, ça peut causer des incompréhensions.
Je sais, je suis maniac... hmm


OS : Ubuntu 14.04 / Debian Weezy / Ubuntu server 12.04

Avec Linux t'as un noyau, avec windows t'as des pépins ;)

Hors ligne

#12 Le 23/09/2014, à 18:29

jibbah

Re : script bash pour compiler deux fichiers

@puiguinman

merci pour la ligne de commande, j'ai dû changer aussi celle définissant "species" en ajoutant une commande head comme ceci (il prenait toute la séquence sinon):

species=`cat $file | cut -d ">" -f2 | head -n +1`

Malheureusement cela ne fonctionne toujours pas. En essayant d'entrer directement dans la console la variable ci-dessus, j'obtiens le message "species : commande introuvable"...

Dernière modification par jibbah (Le 18/09/2017, à 10:59)

Hors ligne

#13 Le 23/09/2014, à 18:46

jibbah

Re : script bash pour compiler deux fichiers

Merci pingouinux pour l'idée de script, après quelques arrangements cela fonctionne presque:

#!/bin/bash
for file in GAPDH/*.fas
	do
	species=`cat $file | cut -d ">" -f2 | head -n +1`
		if [ -f IDH/"${species}"_IDH.fas ]; 
		then
			cat "$file" | tail -n +2 IDH/"${species}"_IDH.fas >>"${species}"_GAPDH_IDH_compil.fas
		else
			echo "IDH/${species}_IDH.fas non trouvé"
    		fi
	done
exit

J'obtiens mes fichiers finaux avec mes séquences concaténées, seul couic, la première ligne du fichier ">Crambus_uliginosellus" a été supprimée... (sûrement lors de species=`cat $file | cut -d ">" -f2 | head -n +1`), pourriez-vous m'aider avec ce dernier petit accroc ?

Dernière modification par jibbah (Le 18/09/2017, à 11:01)

Hors ligne

#14 Le 23/09/2014, à 19:03

pingouinux

Re : script bash pour compiler deux fichiers

Peux-tu donner un petit exemple de tes fichiers (pour 2 espèces et 2 gènes, quelques lignes par fichier), en montrant ce que tu souhaites obtenir.

Hors ligne

#15 Le 23/09/2014, à 19:10

jibbah

Re : script bash pour compiler deux fichiers

Alors dans le dossier GAPDH/ j'ai le fichier Crambus_uliginosellus_GAPDH.fas qui se présente comme suit:
>Crambus_uliginosellus
GCCTCTGCTCACTTGGAAGGTGGGGCTAAGAAAGTCATCATATCTGCTCCCAGTGCTGACGCGCCCATGTACGTGGTCGG

Et le fichier Eudonia_mercurella_GAPDH.fas:
>Eudonia_mercurella
GCGTCTGCTCACTTGGAAGGTGGAGCAAAGAAGGTAATCATCTCTGCACCCAGTGCTGATGCACCCATGTATGTGGTTGG

Dans le dossier IDH/, on a le fichier Crambus_uliginosellus_IDH.fas
>Crambus_uliginosellus
TTGGATATTGAGTTGCACACATATGATTTGGGTATGGAAAACCGTGATGCTACTGATGACCAAGTTACTATTGATTGCGC
AAATGCTATTAAGAAATATAACGTCGGCATCAAGTGCGCCACTATTACTCCCGATGAAAAGCGCGTTGAAGAATTCAAGC

et Eudonia_mercurella_IDH.fas:
>Eudonia_mercurella
?????????????????????????????????????????????????AGACTGATGACCAAgTAACAATTGACTGTGC
TAATGCTATTAAgAAATATAATGTTGGCATCAAATGTGCAACCATTACACCCGATGAGAACCGTGTCAAAGAGTTCAAGC

Hors ligne

#16 Le 23/09/2014, à 19:23

jibbah

Re : script bash pour compiler deux fichiers

Si je change l'ordre je n'obtiens plus qu'une seule des deux séquences, toujours sans l'entête.. sad
Ce que je ne saisis pas, c'est qu'en définissant la variable species, l'entête (>Crambus_uliginosellus) est-elle supprimée pour la suite de la boucle par les commandes cut et head ?

Hors ligne

#17 Le 23/09/2014, à 19:27

pingouinux

Re : script bash pour compiler deux fichiers

Peux-tu montrer ce que tu souhaites obtenir (1 seul fichier suffira) ?

Hors ligne

#18 Le 23/09/2014, à 19:35

jibbah

Re : script bash pour compiler deux fichiers

Les fichiers Eudonia_mercurella_GAPDH.fas

>Eudonia_mercurella
GCGTCTGCTCACTTGGAAGGTGGAGCAAAGAAGGTAATCATCTCTGCACCCAGTGCTGATGCACCCATGTATGTGGTTGG

et Eudonia_mercurella_IDH.fas

>Eudonia_mercurella
?????????????????????????????????????????????????AGACTGATGACCAAgTAACAATTGACTGTGC
TAATGCTATTAAgAAATATAATGTTGGCATCAAATGTGCAACCATTACACCCGATGAGAACCGTGTCAAAGAGTTCAAGC

doivent être concaténés comme suit (la séquence sans l'entête du deuxième fichier est ajoutée au premier fichier):
>Eudonia_mercurella
GCGTCTGCTCACTTGGAAGGTGGAGCAAAGAAGGTAATCATCTCTGCACCCAGTGCTGATGCACCCATGTATGTGGTTGG
?????????????????????????????????????????????????AGACTGATGACCAAgTAACAATTGACTGTGC
TAATGCTATTAAgAAATATAATGTTGGCATCAAATGTGCAACCATTACACCCGATGAGAACCGTGTCAAAGAGTTCAAGC

Merci !

Hors ligne

#19 Le 23/09/2014, à 19:39

pingouinux

Re : script bash pour compiler deux fichiers

Le script que je t'ai indiqué en #10 fait normalement l'affaire. Tu peux éventuellement remplacer ces 2 lignes (lecture de l'espèce dans le nom du fichier)

    species=${file%_*}
    species=${species#*/}

par celle-ci (lecture de l'espèce sur la 1ère ligne du fichier)

    species=$(sed -n '1s/>//p' "$file")

Hors ligne

#20 Le 23/09/2014, à 19:41

pinguinman

Re : script bash pour compiler deux fichiers

#!/bin/bash
for file in GAPDH/*.fas
    do
    species=`cat $file | cut -d ">" -f2 | head -n +1`
        if [ -f IDH/"${species}"_IDH.fas ];
        then
            # je décompose un peu même si le code était bon, je trouve ça plus lisible
            cat "$file" >"${species}"_GAPDH_IDH_compil.fas
            cat IDH/"${species}"_IDH.fas | tail -n +2 >>"${species}"_GAPDH_IDH_compil.fas
        else
            echo "IDH/${species}_IDH.fas non trouvé"
            fi
    done
exit


OS : Ubuntu 14.04 / Debian Weezy / Ubuntu server 12.04

Avec Linux t'as un noyau, avec windows t'as des pépins ;)

Hors ligne

#21 Le 23/09/2014, à 19:44

pingouinux

Re : script bash pour compiler deux fichiers

Et si tu ne veux pas l'en-tête du 2ème fichier

#!/bin/bash
for file in GAPDH/*.fas
do
    species=$(sed -n '1s/>//p' "$file")
    if [ -f IDH/"${species}"_IDH.fas ]; then
       cp "$file" "${species}"_GAPDH_IDH_compil.fas
       tail -n +2 IDH/"${species}"_IDH.fas >>"${species}"_GAPDH_IDH_compil.fas
    else
       echo "IDH/${species}_IDH.fas non trouvé"
    fi
done

Hors ligne

#22 Le 23/09/2014, à 20:01

jibbah

Re : script bash pour compiler deux fichiers

Les deux solutions marchent parfaitement, merci beaucoup ! Je vais maintenant essayer de l'adapter pour que l'utilisateur puisse entrer le chemin des dossiers et le nombre de gènes désirés. Je reposterai un message si j'ai à nouveau besoin d'aide (probablement !).

Hors ligne

#23 Le 23/09/2014, à 20:09

pingouinux

Re : script bash pour compiler deux fichiers

Un peu plus court, avec awk

#!/bin/bash
for file in GAPDH/*.fas
do
    species=$(sed -n '1s/>//p' "$file")
    if [ -f IDH/"${species}"_IDH.fas ]; then
       awk 'FNR>1 || NR==FNR' "$file" IDH/"${species}"_IDH.fas >"${species}"_GAPDH_IDH_compil.fas
    else
       echo "IDH/${species}_IDH.fas non trouvé"
    fi
done

Modifié : Simplification

Dernière modification par pingouinux (Le 23/09/2014, à 20:44)

Hors ligne

#24 Le 24/09/2014, à 15:39

jibbah

Re : script bash pour compiler deux fichiers

Merci pour les réponses. J'ai réécrit le script complet, il fonctionne, mais il me semble bien long, je pense qu'on peut raccourcir certains pas. Le script fait à partir d'un fichier gene1.fas comme ceci:
>Crambus_uliginosellus
ATTGCGTCTAGCTACC
>Eudonia_truncicolella
ACGTCTCGTATCTACG

et gene2 comme cela:
>Crambus_uliginosellus
GGTAGTATGCCCTACT
>Eudonia_truncicolella
ATTCGTATCCGAANNN

des fichiers de la sorte:
Crambus_uliginosellus_gene1_gene2:
>Crambus_uliginosellus
ATTGCGTCTAGCTACCGGTAGTATGCCCTACT
Eudonia_truncicolella_gene1_gene2:
>Eudonia_truncicolella
ACGTCTCGTATCTACG

Voici le script:

#!/bin/bash
# compil together the desired number of genes from individual gene files
# enter the input parameters
echo -n "Enter the name of the first gene: "
read gene1
echo -n "Enter the path to the folder containing the alignment for this gene: "
read pathgene1
echo -n "Enter the name of the second gene to be appended: "
read gene2
echo -n "Enter the path to the folder containing the alignment for this gene: "
read pathgene2

# creates the folder with the files required
mkdir output_conc
cp "$pathgene1"$gene1.fas output_conc
cp "$pathgene2"$gene2.fas output_conc

# split the alignments of gene 1 & 2 into individual files
for file in output_conc/*.fas
	do
	csplit -z $file '/^>/' '{*}' --suffix="%02d.fas" --prefix=$file- -s
done

mkdir output_conc/gene_alignments
mv output_conc/$gene1.fas output_conc/gene_alignments
mv output_conc/$gene2.fas output_conc/gene_alignments

# rename the files split
mkdir output_conc/$gene1
for file in output_conc/$gene1.fas*.fas
	do
	species=$(sed -n '1s/>//p' $file)
	mv $file output_conc/$gene1/"$species"_$gene1.fas
done

mkdir output_conc/$gene2
for file in output_conc/$gene2.fas*.fas
	do
	species=$(sed -n '1s/>//p' $file)
	mv $file output_conc/$gene2/"$species"_$gene2.fas
done

# copy the files of the second gene to the first one
mkdir output_conc/conc_files

for file in output_conc/$gene1/*.fas
	do
	species=$(sed -n '1s/>//p' $file)
    	if [ -f output_conc/$gene2/"${species}"_$gene2.fas ]; 
	then
       		cp $file output_conc/conc_files/"${species}"_"$gene1"_"$gene2".fas 
       		tail -n +2 output_conc/$gene2/"${species}"_$gene2.fas >> output_conc/conc_files/"${species}"_"$gene1"_"$gene2".fas
    	else
       		echo "output_conc/$gene2/"${species}"_$gene2.fas not found"
   	fi
done
exit

Je désirerais entre autre éviter les deux pas consistant à renommer les fichiers créés par la commande csplit, et à la place indiquer directement à la commande csplit de renommer chaque fichier généré par le nom de l'espèce, que l'on obtient avec la commande sed dans les autres boucles (species=$(sed -n '1s/>//p' $file)).
Savez-vous comment faire cela ?

Merci

Dernière modification par jibbah (Le 18/09/2017, à 11:04)

Hors ligne