#1 Le 23/09/2014, à 14: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, à 09:56)
Hors ligne
#2 Le 23/09/2014, à 15: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, à 15: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, à 15: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, à 15: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, à 15: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, à 09:56)
Hors ligne
#6 Le 23/09/2014, à 16: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, à 16: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, à 16: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, à 16: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, à 16: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, à 17: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, à 17:22)
Hors ligne
#11 Le 23/09/2014, à 17: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...
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, à 17: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, à 09:59)
Hors ligne
#13 Le 23/09/2014, à 17: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, à 10:01)
Hors ligne
#14 Le 23/09/2014, à 18: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, à 18: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, à 18: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..
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, à 18: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, à 18: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, à 18: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, à 18: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, à 18: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, à 19: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, à 19: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, à 19:44)
Hors ligne
#24 Le 24/09/2014, à 14: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, à 10:04)
Hors ligne