Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
4024 connectés 

  FORUM HardWare.fr
  Programmation
  Perl

  (débutante) cut

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

(débutante) cut

n°1388470
mayapour
Posté le 15-06-2006 à 21:21:56  profilanswer
 

Bonjour,
 
Je cherche à faire un petit script en PERL qui lira l'entree standard et delimitera celle-ci en colonnes  
avec comme caractere separateur l'espace. On prend en parametre la liste des colonnes à afficher.
 
Pour exemple quand je lance :
$>cat -e file_test | mon_script.pl 1 7 3 5
Je veux afficher :
les colonnes 1 3 5 et 7 du fichier file_test  (les colonnes sont uniquement compossés de chiffres en dur séparés par un espace)
 
Je ne sais pas par où commencer ?
 
Des idées ?
 
MERCI de m'éclairer ...


Message édité par mayapour le 15-06-2006 à 21:32:17
mood
Publicité
Posté le 15-06-2006 à 21:21:56  profilanswer
 

n°1388476
couak
Posté le 15-06-2006 à 21:42:13  profilanswer
 

pour commencer, essaye de récupérer les paramètres passé par la ligne de commande (indice : faire des recherches sur le mot clé STDIN)

n°1388503
lami20j
Posté le 15-06-2006 à 22:33:32  profilanswer
 

Désolé, mauvais manip, message en double.
 
lami20j


Message édité par lami20j le 15-06-2006 à 22:39:44
n°1388508
lami20j
Posté le 15-06-2006 à 22:38:11  profilanswer
 

Salut,
 
Voilà un exemple en utilisant le fichier /etc/passwd ( le séparateur sera : )
Tu n'as qu'à remplacer : avec \s
1. avec handle F_LIRE

Code :
  1. #!/usr/bin/perl
  2. #
  3. use warnings;use strict;
  4. open F_LIRE,"/etc/passwd"
  5.         or die "E/S : $!\n";
  6. my @file;
  7. while (<F_LIRE> ){
  8.         push @file, [split /:/,$_ ];
  9. }
  10. foreach (@file){
  11.         print "@$_[@ARGV]\n";
  12. }

Résultat

Code :
  1. lami20j@debian:~/bin/my_deb_perl$ ./dvz_cut.pl 0 2 3
  2. root 0 0
  3. daemon 1 1
  4. bin 2 2
  5. sys 3 3
  6. sync 4 65534
  7. games 5 60
  8. man 6 12
  9. lp 7 7
  10. mail 8 8
  11. news 9 9
  12. uucp 10 10
  13. proxy 13 13
  14. www-data 33 33
  15. backup 34 34
  16. list 38 38
  17. irc 39 39
  18. gnats 41 41
  19. nobody 65534 65534
  20. Debian-exim 102 102
  21. lami20j 1000 1000
  22. messagebus 100 103
  23. hal 104 104
  24. sshd 101 65534
  25. vdr 103 106
  26. ubucorgeon 1001 1001


2. ce que tu demandes (avec cat)

Code :
  1. #!/usr/bin/perl
  2. #
  3. use warnings;use strict;
  4. my @file;
  5. my @col = @ARGV;
  6. @ARGV=();
  7. while (<> ){
  8.         push @file, [split /:/,$_ ];
  9. }
  10. foreach (@file){
  11.         print "@$_[@col]";
  12. }

Le résultat

Code :
  1. lami20j@debian:~/bin/my_deb_perl$ cat -e /etc/passwd | ./dvz_cut2.pl 0 2 6
  2. root 0 /bin/bash$
  3. daemon 1 /bin/sh$
  4. bin 2 /bin/sh$
  5. sys 3 /bin/sh$
  6. sync 4 /bin/sync$
  7. games 5 /bin/sh$
  8. man 6 /bin/sh$
  9. lp 7 /bin/sh$
  10. mail 8 /bin/sh$
  11. news 9 /bin/sh$
  12. uucp 10 /bin/sh$
  13. proxy 13 /bin/sh$
  14. www-data 33 /bin/sh$
  15. backup 34 /bin/sh$
  16. list 38 /bin/sh$
  17. irc 39 /bin/sh$
  18. gnats 41 /bin/sh$
  19. nobody 65534 /bin/sh$
  20. Debian-exim 102 /bin/false$
  21. lami20j 1000 /bin/bash$
  22. messagebus 100 /bin/false$
  23. hal 104 /bin/false$
  24. sshd 101 /bin/false$
  25. vdr 103 /bin/false$
  26. ubucorgeon 1001 /bin/bash$

lami20j


Message édité par lami20j le 15-06-2006 à 22:49:16
n°1388517
lami20j
Posté le 15-06-2006 à 22:48:05  profilanswer
 

Re,
 
à la place de

Code :
  1. my @col = @ARGV;
  2. @ARGV=();

on peut écrire

Code :
  1. my @col = splice(@ARGV,0,@ARGV);

lami20j

n°1388528
mayapour
Posté le 15-06-2006 à 23:00:58  profilanswer
 

MERCI pour tes réponses :
Mais avec cat -e file_test | ./mon_script.pl 1 2 6
J'obtient :
use: Command not found.
use: Command not found.
my: Command not found.
Badly placed ()'s.

n°1388533
lami20j
Posté le 15-06-2006 à 23:12:23  profilanswer
 

Re,

mayapour a écrit :

MERCI pour tes réponses :
Mais avec cat -e file_test | ./mon_script.pl 1 2 6
J'obtient :  
use: Command not found.
use: Command not found.
my: Command not found.
Badly placed ()'s.

tu peux afficher ici ton fichier? aussi le code que tu as écrit?
 
Pour voir où se trouve l'erreur.Merci.
 
lami20j

n°1388539
mayapour
Posté le 15-06-2006 à 23:16:09  profilanswer
 

Monfichier file_test :
a1 a2 a3 a4 a5 a6
b1 b2 b3 b4 b5 b6 b7 b8 b9
c1 c2 c3 c4
d1 d2 d3 d4 d5 d6 d7 d8 d9
e1 e2
 
Mon code (enfin le tien;-)):
#!/usr/pkg/bin/perl -w
 
@col = splice(@ARGV,0,@ARGV);      
 
while (<> ){
 
       push @file, [split /:/,$_ ];
 
      }
 
   foreach (@file){
 
       print "@$_[@col]";
}
 
Avec la commande cat -e file_test | ./mon_script.pl 1 2 6
J'obient maintenant : Badly placed ()'s.

n°1388543
lami20j
Posté le 15-06-2006 à 23:27:17  profilanswer
 

Re,
 
tu n'as pas remplacer les deux-points : avec un espace \s
 
Ensuite le problème se complique un peu vu que les chaines n'ont pas le même nombre de termes separés par un espace.
 
Donc tu auras des messages d'erreurs concerntant l'initialisation des valeurs.
 
lami20j

n°1388544
lami20j
Posté le 15-06-2006 à 23:27:47  profilanswer
 

toujours des mauvaises manipulations :(


Message édité par lami20j le 15-06-2006 à 23:28:48
mood
Publicité
Posté le 15-06-2006 à 23:27:47  profilanswer
 

n°1388546
mayapour
Posté le 15-06-2006 à 23:31:14  profilanswer
 

J'ai remplacé les deux points par \s
Mais effectivement pas mieux :/


Message édité par mayapour le 15-06-2006 à 23:31:33
n°1388562
lami20j
Posté le 16-06-2006 à 00:03:00  profilanswer
 

Re,
 
essaie ça. Ce n'est pas excellent(j'ai enlevé l'option -w pour ne pas voir les messages d'erreurs)
Il y a un antislash avant le s dans la regex de split

Code :
  1. #!/usr/bin/perl
  2. #
  3. @col = splice(@ARGV,0,@ARGV);
  4. while (<> ){
  5.      push @file, [split /\s/,$_ ];
  6. }
  7. foreach (@file){
  8.     print "@$_[@col]\n";
  9. }

Chez moi ça marche

Code :
  1. lami20j@debian:~/bin/my_deb_perl$ cat maya
  2. a1 a2 a3 a4 a5 a6
  3. b1 b2 b3 b4 b5 b6 b7 b8 b9
  4. c1 c2 c3 c4
  5. d1 d2 d3 d4 d5 d6 d7 d8 d9
  6. e1 e2
  7. lami20j@debian:~/bin/my_deb_perl$ cat maya | ./dvz_cut3.pl 1 2 6
  8. a2 a3
  9. b2 b3 b7
  10. c2 c3
  11. d2 d3 d7
  12. e2
  13. lami20j@debian:~/bin/my_deb_perl$

lami20j


Message édité par lami20j le 16-06-2006 à 00:08:13
n°1388564
lami20j
Posté le 16-06-2006 à 00:03:54  profilanswer
 

toujours en double  :(  j'arrête pour ce soir. bonne continuation. lami20j


Message édité par lami20j le 16-06-2006 à 00:07:29
n°1388570
mayapour
Posté le 16-06-2006 à 00:09:55  profilanswer
 

Je ne comprend pas pourquoi : idem
Badly placed ()'s.
 
???
 
MERCI pour cette solution qui me semble devoir fontionner ;-)

n°1388640
lami20j
Posté le 16-06-2006 à 09:27:06  profilanswer
 

Salut,

mayapour a écrit :

Je ne comprend pas pourquoi : idem
Badly placed ()'s.
 
???
 
MERCI pour cette solution qui me semble devoir fontionner ;-)


Essaie d'exécuter avec

Code :
  1. cat -e file_test | perl ./mon_script.pl 1 2 6


 
Pour ton erreur  
 
Badly placed ()'s
 
(A) Vous lancez accidentellement votre script par csh au lieu de Perl. Vérifiez la ligne avec #!, ou lancez votre script manuellement dans Perl.  
 
(A) Erreur externe (non générée par Perl).
 
Ca pourra te servir à l'avenir :
http://perl.enstimac.fr/DocFr/perldiag.html
 
lami20j


Message édité par lami20j le 16-06-2006 à 09:28:48
n°1388891
lami20j
Posté le 16-06-2006 à 12:07:03  profilanswer
 

Re,
 
Peut être je devrais le devrait le faire de début pour comprendre ce que j’ai fait. Mea culpa.

Code :
  1. while (<> ){
  2.   push @file, [split /s/,$_ ];
  3. }


 
while (<> ) va lire la sortie de cat fichier et dans la boucle je stocke dans un tableau des tableaux les éléments dont le séparateur est l’espace.

Code :
  1. @col = splice(@ARGV,0,@ARGV);


Cette ligne stocke dans @col les arguments et vide @ARGV.
Pourquoi ?  
Puisque la boucle while(<> ) lit dans @ARGV et comme 2, 3 et 4 ne sont pas des fichiers une exception sera levée.  
Une fois @ARGV vide <> va lire seulement depuis pipe |

Code :
  1. foreach (@file){
  2.   print "@$_[@col]\n";
  3. }


Pour affichage on va utiliser une tranche de tableau.
Comme @col contient les arguments 2, 4 et 6 par exemple je vais afficher pour chaque élément (qui est un tableau anonyme) du @file, uniquement les éléments 2, 4 et 6 qui correspondent à la colonne 3, 5 et 7 de ton fichier.  
En suivant cet algo (à savoir que ce n’est pas le meilleur et en plus quand on est en Perl il ne faut pas oublier TMTOWTDI – There’s More Than One Way To Do It – Il y a plusieurs façon de le faire) tu peux écrire toi-même le code ainsi tu comprendras mieux et tu éviteras aussi les erreurs de syntaxe.
 
A savoir que tu auras toujours des messages Warning si les lignes de ton fichier ne contiennent pas le même nombre d’éléments. Donc peut être il faut une autre approche pour traiter ça.
Un warning n’est pas forcément une erreur mais une information.
Si tu enlèves –w ou use warnings tu n’auras pas les messages warnings. A toi de voir.
Je vais penser pour une autre approche.
Par exemple tu peux utiliser la commande cut dant ton script (voir man cut). Tu peux le faire avec la fonctin system  
(voir dans la doc - http://perl.enstimac.fr/DocFr/perl [...] em_system)
Si tu ne comprends pas, fait un signe. Merci.
 
lami20j


Message édité par lami20j le 16-06-2006 à 12:28:03
n°1390855
mayapour
Posté le 19-06-2006 à 17:45:08  profilanswer
 

Merci pour toute ton aide lami20j !


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Perl

  (débutante) cut

 

Sujets relatifs
(débutante) reverse[débutante] Interfaçage C++/C
plus que débutante en TeXgraphise (debutante)
[Débutante] Découpage logique des classes ?super débutante lecteur code barre
le rollover expliqué à une débutante ??je suis débutante help me !!!plz
debutante en c++ cherche coursDébutante SQL : modélisation système train
Plus de sujets relatifs à : (débutante) cut


Copyright © 1997-2025 Groupe LDLC (Signaler un contenu illicite / Données personnelles)