Unix - eliminer des colonnes .txt
Résolu/Fermé
A voir également:
- Unix - eliminer des colonnes .txt
- Comment faire des colonnes sur word - Guide
- Classer par ordre alphabétique excel plusieurs colonnes - Guide
- Figer des colonnes excel - Guide
- Déplacer des colonnes excel - Guide
- Fusionner 2 colonnes excel - Guide
4 réponses
dubcek
Messages postés
18764
Date d'inscription
lundi 15 janvier 2007
Statut
Contributeur
Dernière intervention
9 février 2025
5 624
14 nov. 2011 à 12:37
14 nov. 2011 à 12:37
hello
la colonne 5 contient moins de 80% de -, c'est pour cela que je teste <75
la colonne 5 contient moins de 80% de -, c'est pour cela que je teste <75
$ cat a1 --at-gg--- --at-gga-- --at-gtcg- --atgtgtt- $ $ awk '{x[NR]=$0}END{for(i=1;i<=10;i++){for(n=1;n<=NR;n++){if(substr(x[n],i,1)=="-")c[i]++} ;col[i]=(100*c[i])/NR} ; for(n=1;n<=NR;n++){for(i=1;i<=10;i++){if(col[i]<75)printf substr(x[n], i, 1)} print ""}}' a1 atgg-- atgga- atgtcg attgtt $ $
mamiemando
Messages postés
33535
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
12 février 2025
7 828
14 nov. 2011 à 20:40
14 nov. 2011 à 20:40
En fait si je résume cette longue discussion c'est que le pourcentage seuil (80%) est relatif à chaque colonne, ce qui force à lire l'ensemble des lignes pour savoir si la colonne est conservée ou non.
À mon avis il n'y a pas quarante solutions, il faut lire toutes les lignes, les stocker en mémoire, et parcourir la structure ainsi lue. A peu près n'importe quel langage de programmation permet de le faire.
Personnellement je fais plutôt du C++, mais si tu préfères le python ou n'importe quoi d'autre pourquoi pas...
Source (toto.cpp)
Avec ce fichier d'entrée (input.txt) :
Il faut à présent installer un compilateur (par exemple g++ sous linux ou code::blocks sous windows). Par exemple sous linux (ubuntu, debian...) :
On compile notre programme (appelons le par exemple convertir.exe) :
On obtient le fichier output.txt :
... ce qui est le bon résultat si j'ai bien pigé.
À l'époque tu avais dit que normalement la sortie était :
... mais la colonne qui contient (-,-,-,g) contient seulement 75% de '-' soit moins de 80%, donc normalement on la conserve...
Bonne chance
À mon avis il n'y a pas quarante solutions, il faut lire toutes les lignes, les stocker en mémoire, et parcourir la structure ainsi lue. A peu près n'importe quel langage de programmation permet de le faire.
Personnellement je fais plutôt du C++, mais si tu préfères le python ou n'importe quoi d'autre pourquoi pas...
Source (toto.cpp)
#include <fstream> #include <vector> #include <iostream> #include <string> int main(int argc, char **argv){ const char *filename_in = argv[1], *filename_out = argv[2]; const unsigned int num_chars = 10; // Chaque ligne valide doit comporter 10 caractères const unsigned int threshold = 80; // 80 % unsigned int num_lines = 0; std::string line; std::ifstream ifs; std::ofstream ofs; std::vector<std::string> lines; std::vector<unsigned int> num_minus(num_chars, 0); std::vector<bool> column_to_write(num_chars); if(argc != 3) { std::cerr << "usage: " << argv[0] << " input_file output_file" << std::endl; goto END; } // Ouvrir le fichier d'entrée ifs.open(filename_in); if(!ifs) { std::cerr << argv[0] << ": can't read " << filename_in << std::endl; goto END; } // Ouvrir le fichier de sortie ofs.open(filename_out); if(!ofs) { std::cerr << argv[0] << ": can't write " << filename_out << std::endl; goto END; } // Charger les lignes en mémoire et compter le nombre de '-' while(std::getline(ifs, line)) { if(line.size() == num_chars){ for(std::size_t i = 0; i < num_chars; ++i){ if(line[i] == '-') ++num_minus[i]; } lines.push_back(line); ++num_lines; } } // Quelles colonnes doit on réécrire ? for(std::size_t i = 0; i < num_chars; ++i){ column_to_write[i] = ((100 * num_minus[i] / num_lines) < threshold); } // Écrire les lignes en ne conservant que le nécessaire for(std::size_t i = 0; i < lines.size(); ++i){ for(std::size_t j = 0; j < num_chars; ++j){ if(column_to_write[j]){ ofs << lines[i][j]; } } ofs << std::endl; } END: // On ferme proprement if(ifs) ifs.close(); if(ofs) ofs.close(); return 0; }
Avec ce fichier d'entrée (input.txt) :
--at-gg--- --at-gga-- --at-gtcg- --atgtgtt-
Il faut à présent installer un compilateur (par exemple g++ sous linux ou code::blocks sous windows). Par exemple sous linux (ubuntu, debian...) :
sudo apt-get update sudo apt-get install g++
On compile notre programme (appelons le par exemple convertir.exe) :
(mando@aldur) (~) $ g++ -W -Wall toto.cpp -o convertir.exe (mando@aldur) (~) $ ./convertir input.txt output.txt
On obtient le fichier output.txt :
at-gg-- at-gga- at-gtcg atgtgtt
... ce qui est le bon résultat si j'ai bien pigé.
À l'époque tu avais dit que normalement la sortie était :
atgg-- atgga- atgtcg attgtt
... mais la colonne qui contient (-,-,-,g) contient seulement 75% de '-' soit moins de 80%, donc normalement on la conserve...
Bonne chance
zipe31
Messages postés
36402
Date d'inscription
dimanche 7 novembre 2010
Statut
Contributeur
Dernière intervention
27 janvier 2021
6 422
14 nov. 2011 à 09:59
14 nov. 2011 à 09:59
Salut,
Rien pigé à ton histoire de 80% ;-((
Sur la ligne 2, pourquoi t'élimines les 2 premiers et qu'un seul sur les 2 derniers ???
Rien pigé à ton histoire de 80% ;-((
Sur la ligne 2, pourquoi t'élimines les 2 premiers et qu'un seul sur les 2 derniers ???
--at-gga-- => atgga-
En fait il faut lire en colonne :
la premiere colonne ne contient que des - (donc 100% de -), elle degage
la deuxieme idem
la troisieme ne contient pas de - (il n'a que des a), elle reste
etc
l'avant dernier ne contient que deux - (et un g et un t), donc elle reste (50% de -)
et la derniere ne contient que des -, elle degage
J'espere avoir reussi a etre clair cette fois
Merci
Alex
la premiere colonne ne contient que des - (donc 100% de -), elle degage
la deuxieme idem
la troisieme ne contient pas de - (il n'a que des a), elle reste
etc
l'avant dernier ne contient que deux - (et un g et un t), donc elle reste (50% de -)
et la derniere ne contient que des -, elle degage
J'espere avoir reussi a etre clair cette fois
Merci
Alex
zipe31
Messages postés
36402
Date d'inscription
dimanche 7 novembre 2010
Statut
Contributeur
Dernière intervention
27 janvier 2021
6 422
14 nov. 2011 à 10:15
14 nov. 2011 à 10:15
En fait il faut lire en colonne
Ok, mais à quoi reconnaît-on une colonne ???
Ok, mais à quoi reconnaît-on une colonne ???
zipe31
Messages postés
36402
Date d'inscription
dimanche 7 novembre 2010
Statut
Contributeur
Dernière intervention
27 janvier 2021
6 422
14 nov. 2011 à 10:24
14 nov. 2011 à 10:24
Tes explications sont complètement incohérentes ;-((
la premiere colonne ne contient que des - (donc 100% de -), elle degage
la deuxieme idem
En considérant que chaque caractère est en fait une colonne à lui tout seul, nous sommes d'accord ;-\
la troisieme ne contient pas de - (il n'a que des a), elle reste
etc
Idem qu'au-dessus ;-\
l'avant dernier ne contient que deux - (et un g et un t), donc elle reste (50% de -)
C'est là où ça se corse ;-((
Pourquoi subitement ta colonne contient plusieurs caractères et commence à mélanger caractères alphanumériques avec des caractères non-alphanumériques ???
Où est la logique dans tout ça ??? ;-\
la premiere colonne ne contient que des - (donc 100% de -), elle degage
la deuxieme idem
En considérant que chaque caractère est en fait une colonne à lui tout seul, nous sommes d'accord ;-\
la troisieme ne contient pas de - (il n'a que des a), elle reste
etc
Idem qu'au-dessus ;-\
l'avant dernier ne contient que deux - (et un g et un t), donc elle reste (50% de -)
C'est là où ça se corse ;-((
Pourquoi subitement ta colonne contient plusieurs caractères et commence à mélanger caractères alphanumériques avec des caractères non-alphanumériques ???
Où est la logique dans tout ça ??? ;-\
il s'agit de sequences d'ADN (succession de molecules A T C et G pour Adenosine, Guanine, Thymine, Custeine) qui sont alignees selon leur similarite, imaginons:
gene humain ATGCT - -TCGCT
gene mouche ATGCTTGTCGCT
gene meduse ATCGT - -TCGCT
Ces genes sont identiques chez les trois organismes (humain, mouche , meduse), sauf que dans la sequence genetique de la mouche, il y a deux molecules en plus, un T et un G.
Ce molecules absente chez l'homme et la meduse sont representes par des tirets.
Ce que je voudrais c'est conserver cet alignement tou en eliminant les zones contenant beaucoup de tirets, c'est a dire les zones genetiques peu conservees entre differentes especes.
Voila, j'espere que c'est plu clair pour toi
Alex
gene humain ATGCT - -TCGCT
gene mouche ATGCTTGTCGCT
gene meduse ATCGT - -TCGCT
Ces genes sont identiques chez les trois organismes (humain, mouche , meduse), sauf que dans la sequence genetique de la mouche, il y a deux molecules en plus, un T et un G.
Ce molecules absente chez l'homme et la meduse sont representes par des tirets.
Ce que je voudrais c'est conserver cet alignement tou en eliminant les zones contenant beaucoup de tirets, c'est a dire les zones genetiques peu conservees entre differentes especes.
Voila, j'espere que c'est plu clair pour toi
Alex
mamiemando
Messages postés
33535
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
12 février 2025
7 828
Modifié par mamiemando le 14/11/2011 à 10:00
Modifié par mamiemando le 14/11/2011 à 10:00
Oui tu peux t'en sortir avec awk.
$0 désigne la ligne courante, affecte là à s.
length(s) permet de calculer la longueur de s.
Crée un compteur (par exemple num_minus) initialisé à 0.
Dans une boucle for allant de 0 à length(s) - 1 :
- substr(s, i, 1) permet d'extraire le i-ème caractère.
- si c'est un tiret, incrémente ton compteur num_minus
Une fois la boucle for, calcule le pourcentage (100 * num_minus / length(s)). S'il est supérieur à ton seuil de 80, print $0.
Bonne chance
man awk
$0 désigne la ligne courante, affecte là à s.
length(s) permet de calculer la longueur de s.
Crée un compteur (par exemple num_minus) initialisé à 0.
Dans une boucle for allant de 0 à length(s) - 1 :
- substr(s, i, 1) permet d'extraire le i-ème caractère.
- si c'est un tiret, incrémente ton compteur num_minus
Une fois la boucle for, calcule le pourcentage (100 * num_minus / length(s)). S'il est supérieur à ton seuil de 80, print $0.
Bonne chance
14 nov. 2011 à 13:18
Ca marche a merveille!
Je vais essayer de décortiquer pour comprendre, mais j'avoue que quelques explication seraient les bienvenues.
Merci encore beaucoup
Alex
14 nov. 2011 à 15:42