Aide:extraire un groupe de données depuis un groupe de fichiers - Shell/Batch - Programmation
Marsh Posté le 07-02-2015 à 20:52:20
hum, j ai trouvé une autre approche, mais ca ne marche que dans un seul dossier.
(ca donne le string complet " $$ Acquired Time: 15:13:10 " mais bon c'est deja mieux que rien)
est ce que quelqu'un peux m'aider pour modifier ce code pour que ca extrait ce string pour chaque dossier?
Code :
|
Marsh Posté le 09-02-2015 à 23:43:27
Merci Beaucoup Phoenix
J'ai essayé les deux scripts, et aucun des deux ne renvoient de données du tout malheureusement.
je vois que le script ce lance, mais le fichier output ne se crée pas.
Comment veux tu que je le teste?
Marsh Posté le 11-02-2015 à 21:37:49
Je bosse dans la science en spectrometry de masse.
J ai un patch qui me permet de recalibrer entre deux echantillions, mais ce process peut prendre plus au moins de temps.
Chaque echantillion a "l'heure" ou il commence dans ce fichier _Header.txt, donc pour pouvoir calculer le "temps moyen" que prend un echantillion je doit extraire manuellement cette heure, les mettre dans excel... ( je fait 96 echantillions par 24 heures, faire tout ca a la main après je suis )
j'ai bidoullé dans tous les sens ce que tu m'as donné ca marche pas
J'ai essayé une autre approche, en utilisant le vba dans excel, mais la autres probleme: je n'arrive pas a extraire a partir d'un fichier qui a le meme nom situé dans different dossier
J'ai cherhé aussi pour un logiciel qui pourrai me permettre de faire ca, aucun ne me le perme ( avec un logiciel comme textcrawler , tu peux faire que des find and replace, pas moyen de faire n find puis metre ca dans un ouput
Marsh Posté le 12-02-2015 à 04:09:17
Pourquoi ne pas faire ça avec un langage de script comme perl ou python?
Ce sont des langages particulièrement adaptés à ce genre de choses.
Code :
|
A+,
Marsh Posté le 12-02-2015 à 23:18:00
Bonsoir Gilou et merci,
je n'ai aucune connaissance en Perl , j 'ai donc installé Perl Active.
A la premiere execution de ton code, j'ai eu un message d'erreur, me demandant fgrep.
J'ai donc utilise ppm, et ai installé File-Grep v 0.02(find matches to a pattern in a series of files and related functions).
Second execution du code, le fichier log.tct se crée mais il est vide
j'ai essayé d'installer File-MultineGrep v0.01 (Match multiple line block delimited by a star/stop pattern) (meme si je ne vois pas de stop pattern dans ton code).
Nouvel essaie, fichier log.txt vide.
J ai assayé App-file-Grepper v0.06 (greps file for pattern).
nouvel essaie, fichier log.txt vide .
Pour le glob, j'ai deja d'installé Text-glob v0.09 (match globing patterns against text).
Ne connaissant pas du tout ce language, je n'arrive pas a voir ou ca pourrait buger
J'ai uploader ici le "dossier type" de données que ma machine me sort (en version allege, avec seulement le fichier _Header.TXT).
Peux tu essayer ton script sur ton pc pour voir si ca vien de mon install de Perl?
http://cjoint.com/?0Bmxz4S4758
Merci
Marsh Posté le 13-02-2015 à 00:51:17
Bonsoir,
1) Tu as installé Active Perl
2) Avec ppm, tu as installé File-Grep
A priori, tu n'as pas besoin de plus.
J'ai testé le zip et ça marchait pas pour moi non plus (bizarre, hier ça marchait dans mes tests) mais je sais pourquoi.
Remplaces
my $pattern = qr("\$\$ Acquired Time:" );
par
my $pattern = qr(\$\$ Acquired Time: );
donc plus de doubles quotes autour, et ça règle le problème.
Pour savoir comment j'ai débuggé:
J'ai ajouté après le use autodie; une ligne
use Data::Dumper;
et après le my @matches = fgrep {/^$pattern/} bsd_glob("$datareg" );
j'ai ajouté une ligne
print Dumper(@matches)
ce qui m'a donné a l'exécution un écran avec
$VAR1 = { |
filename montre que les fichiers étaient trouvés, mais count a 0 montre que le pattern n'était pas trouvé dans le fichier. J'ai modifié le pattern en réfléchissant un peu et j'ai ensuite obtenu ce qu'il fallait:
$VAR1 = { |
Tant que j'y suis je t'explique la suite:
On a dans @matches une liste de 4 structures un peu complexe
foreach my $match (@matches) {
...
}
je parcours la liste mon élément courant est représenté par la variable $match
if ($match->{'count'} == 1) {
...
}
match est une référence sur un hash (une liste de (clé, valeur) les clés étant uniques) de clés count, matches et filename.
avec $match->{'count'} j'accède a la valeur du hash pour la clé count
Je filtre pour les éléments ayant cette valeur a 1 (ie le pattern a été trouvé une fois dans le fichier)
$_ = ((values %{$match->{'matches'}})[0]);
maintenant je m'intéresse a la valeur du hash pour la clé matches. La valeur est a nouveau une référence sur un hash, dont les clés sont les numéros des lignes avec le pattern, et les valeurs les contenus desdites lignes.
Je sais qu'il n'y a qu'une ligne, je veux la récupérer, mais je ne connais pas son numéro de ligne.
%{$match->{'matches'}} déréférence la référence a un hash, et est donc le hash lui même
(values %{$match->{'matches'}}) est la liste des valeurs de ce hash
(values %{$match->{'matches'}})[0] est le premier élément de cette liste (et je sais que c'est le seul).
$_ = ((values %{$match->{'matches'}})[0]); copie cet élément (ie le texte de la ligne qui matche le pattern) dans la variable scalaire par défaut $_
chop vire le \n final d'une ligne, comme il est sans argument, il s'applique à la variable scalaire par défaut $_
s/^$pattern//; élimine le pattern en début de ligne de la variable scalaire par défaut $_
$_ contient maintenant le texte de la ligne sans le pattern initial ni le \n final
push @times, $_;
Je range ce texte dans la liste @times.
EDIT: faut aussi changer le open my $fh, '>>', $datalog; par open my $fh, '>', $datalog; (avec >>, c'est en mode append)
A+,
Marsh Posté le 13-02-2015 à 16:05:05
Et une autre version, un peu plus pédagogique:
On fait pratiquement tout soi même ici, plutôt que de le laisser faire par des modules (sauf le parcours récursif de répertoire, qui utilise un module standard).
Comme on n'a pas de structures de données complexes, c'est plus lisible pour un débutant en perl.
Code :
|
A+,
Marsh Posté le 13-02-2015 à 17:50:36
Et encore une version pédagogique qui ne fait appel à aucun module particulier.
Elle suppose juste que les répertoires en .raw sont tous dans le répertoire Data
Code :
|
Un des principes de perl, c'est qu'il n'y a pas UNE bonne méthode pour faire les choses, mais des méthodes adaptées au niveau de celui qui utilise le script, l'important étant que le script fasse ce qui est voulu.
A+,
Marsh Posté le 18-02-2015 à 00:32:17
Merci Gilou !!!!!!!!!!!
J 'ai testé le premier script que tu as posté et ca marche !!!!!!
Merci beaucoup pour le temps que tu as passé pour l'ecrire.
Je comprends en lisant les deux autres script qu'effectivement il y a beaucoup de " facon d'ecrire"
Je vais essayer de modifier le3 eme script , pour faire deux recherches sur le meme fichier et separer par un point virgule ( ou un tab), afin de pouvoir utiliser le fichier dans excel.
PERL est mon nouvel ami
Gilou est ce que tu connais un bon site pour apprendre le PERL?
(MERCI ENCORE)
Marsh Posté le 18-02-2015 à 12:31:31
Pour écrire au directement au format Excel, il y a le module Excel::Writer::XLSX, ou bien Text::CSV si on veut écrire au format csv.
Il y a pas mal de tutoriels perl plus ou moins bon.
Sur cette page: http://qntm.org/files/perl/perl.html se trouve résumé l'essentiel de ce qu'il y a à savoir sur le langage. Et c'est bien mieux fait que sur pas mal de sites.
Cet article http://matt.might.net/articles/perl-by-example/ est bien aussi.
Ensuite, une bonne méthode est de chercher sur le web des exemples proche de ce qu'on veut faire (google "perl ..." et filtrer les retours sur Perl Monks ou StackOverflow), les comprendre et les adapter a son cas.
A+,
Marsh Posté le 07-02-2015 à 14:01:26
Bonjour, ceci est mon premier post, alors bonjour a tous
je m'inscrit seulement maintenant parce que j'ai un probleme de progammation en BAT. ( level : newbie, recherche sur internet de script deja ecrite que je bricole)
Je cherche a extraire la meme info (heure), dans une serie de fichiers qui ont le meme nom
Je bosse dans la science et mes données sont toutes données sous la formes d'un dossier (*.RAW), qui contient un ensemble de fichier.
-> dossier " Data"
--> dossier " monexperience01.RAW "
---> fichier " _CHRO001.DAT "
---> fichier " _CHRO002.DAT "
.
.
---> fichier "_HEADER.TXT"
--> dossier " monexperience02.RAW "
---> fichier " _CHRO001.DAT "
---> fichier " _CHRO002.DAT "
.
.
---> fichier "_HEADER.TXT"
chaque fichier " _HEADER.TXT " commence par
$$ Version: 01.00
$$ Acquired Name: 20150206_QC_01
$$ Acquired Date: 06-Feb-2015
$$ Acquired Time: 13:34:44
$$ Job Code: 20150206_HEP
$$ Task Code:
$$ User Name:
Donc, j'essaie de programmer un BAT, qui me fait un outpout "temps.log" ayant dedans une liste de la variable " $$ Acquired Time: " pour chaque fichier " _HEADER.TXT "
en ouvrant le fichier " temps.log " j aimerai voir
"
13:34:44
13:49:46
14:04:42
14:19:48
.
.
.
"
le problem: ca marche pas, ca me renvoie toutes les infos
est ce que quelqu'un peux me corriger???
vopic mon BAT
@echo off
(
for /f " skip=3 tokens=1,2 delims=" %%a in ('dir *.txt /a:-d /b /s') do (
for /f " usebackq tokens=1,2 delims==" %%a in ("%%a" ) do (
if not defined skip set /p "=%%a,"<nul
if "%%a"=="$$ Acquired Time:" set skip=3
)
echo(
)
)>"temps.txt"
Message édité par scientista le 07-02-2015 à 21:32:44