IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

Suppression de values en double dans un hash


Sujet :

Langage Perl

  1. #1
    Membre Expert Avatar de dmganges
    Homme Profil pro
    Retraité. Ne recherche pas un emploi.
    Inscrit en
    Septembre 2011
    Messages
    1 425
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Retraité. Ne recherche pas un emploi.
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2011
    Messages : 1 425
    Par défaut Suppression de values en double dans un hash
    Bonjour,

    En vue de tuer des processus connus par leurs noms ex skype.exe contenus dans une liste... j'utilise Win32:: Process::List qui renvoie une liste comme :

    612 services.exe
    2396 sftlist.exe
    2156 sftvsa.exe
    320 smss.exe
    1488 spoolsv.exe
    1844 sqlservr.exe
    2188 sqlwriter.exe
    1168 svchost.exe
    368 svchost.exe
    1044 svchost.exe
    468 svchost.exe
    3364 svchost.exe
    1076 svchost.exe
    768 svchost.exe
    1516 svchost.exe
    120 svchost.exe
    1816 svchost.exe
    848 svchost.exe
    5020 svchost.exe
    2300 svchost.exe
    3596 taskeng.exe
    4404 taskeng.exe
    3552 taskhost.exe
    544 wininit.exe
    664 winlogon.exe
    Voici ce que je fais, qui fonctionne bien et qui me convient amplement, sauf que ça ne ressemble pas beaucoup à du perl

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    #! perl
    use warnings;
    use strict;
    use utf8;
    use Win32::Process::List;									# Liste des processus en cours
    use Win32::Process;												# Pour tuer un processus
     
    my $Proc = Win32::Process::List->new();
    my %ListProc = $Proc->GetProcesses();
    my $NbProc = keys (%ListProc);
     
    print "\n\nAvec doublons sur les noms de process\n";
    foreach my $Pid (sort { $ListProc{$a} cmp $ListProc{$b} } keys %ListProc ) {
    	my $Name = $ListProc{$Pid};
    	printf "%4d %25s\n", $Pid, $ListProc{$Pid};
    }
     
    print "\n\nSuppression...\n";
    my $Name = "" ;
    my $OldName = "";
    foreach my $Pid (sort { $ListProc{$a} cmp $ListProc{$b} } keys %ListProc ) {
    	$Name = $ListProc{$Pid};
    	if ( $Name eq $OldName ) {
    		delete $ListProc{$Pid};
    	}
    	$OldName = $Name;
    }
     
    print "\n\nDoublons supprimés\n";
    foreach my $Pid (sort { $ListProc{$a} cmp $ListProc{$b} } keys %ListProc ) {
    	my $Name = $ListProc{$Pid};
    	printf "%4d %25s\n", $Pid, $ListProc{$Pid};
    }
    J'ai cherché sur le net, probablement mal, mais je n'ai pas trouvé mieux que la méthode à l'ancienne...

    Comment supprimer des values en doubles dans un hash... en perl véritable ?
    MERCI d'avance !

  2. #2
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    Souhaiterais-tu, par exemple, conserver tous les numéros de processus de chaque programme, dans une structure de ce type :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    %process = ( "services.exe" => [ 612 ],
             "svchost.exe" -> [ 1168, 368, ... ],
             ...);
    Si non, quel processus souhaiterais-tu conserver ?

  3. #3
    Membre Expert Avatar de dmganges
    Homme Profil pro
    Retraité. Ne recherche pas un emploi.
    Inscrit en
    Septembre 2011
    Messages
    1 425
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Retraité. Ne recherche pas un emploi.
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2011
    Messages : 1 425
    Par défaut
    Bonjour, et merci Philou67430,

    Non je souhaite seulement récupérer une liste des noms de process (sans les pid), et sans les doublons des noms.

    En fait cette liste me permet de mettre à jour un fichier .ini, à partir duquel :
    - je décide de de killer certains processus (je tue à tour de bras) TOUS les process, même lorsqu'ils existe en plusieurs exemplaires en mémoire [KILL]
    - je contrôle au boot (-2mn) les intrus à partir de [LISTFIRST]
    - je contrôle régulièrement à partir de[LISTNEXT]

    Il me faut seulement construire [LISTNEXT] sans doublons à partir de
    my %ListProc = $Proc->GetProcesses();

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    [GLOBAL]
         Debug: OUI
          Kill: OUI
      Controle: OUI
       NbFirst: 50
        NbNext: 81
     TempoKill: 120000
     
    [OLD]
    Proc: Skype.exe
     
    [KILL]
    Proc: Skype.exe
        : BTTray.exe
        : BluetoothHeadsetProxy.exe
        : BTStackServer.exe
     
    [LISTFIRST]
    Proc: BTTray.exe
        : Skype.exe
        : agent.exe
        : audiodg.exe
        : reader_sl.exe
        : userinit.exe
     
    [LISTNEXT]
    Proc: Admload.exe
        : CVHSVC.EXE
        : IAStorDataMgrSvc.exe
        : IAStorIcon.exe
        : ISBMgr.exe
        : ISUSPM.exe
        : KHALMNPR.exe
        : LMS.exe
        : MsMpEng.exe
        : NisSrv.exe
        : PMBDeviceInfoProvider.exe
        : PMBVolumeWatcher.exe
        : SPMService.exe
        : SPMgr.exe
    etc...
    Actuellement je construis cette liste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    ...
    $ListNextExist = "$ListNextExist$Name\n"; # Je boucle la dessus
    ...
    $Process{LISTNEXT}{Proc} = $ListNextExist;
    write_config %Process, $FicIni;
    Dans $ListNextExist les noms étant séparés par des \n, je n'ai plus qu'à coller dans le fichier...

    En fait dans la suppression des doublons, le pid n'a pas d'importance.

    Encore MERCI

  4. #4
    Membre actif
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration

    Informations forums :
    Inscription : Décembre 2012
    Messages : 43
    Par défaut
    question bête : c'est pour déployer sur un réseau de pc ou juste ton pc personnel ?
    dans le second cas, si j'ai bien compris, tu fonctionnes sous windows, tu as l'utilitaire msconfig pour gérer les programmes qui sont lancés au démarrage.

    sinon, la fonction keys() en perl te renvoie la liste des clés d'un hash, et normalement chaque clé est unique. tu peux ensuite utiliser la fonction sort() pour trier cette liste de clés.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    my $Proc = Win32::Process::List->new();
    my %ListProc = $Proc->GetProcesses();
     
    my @tab_ListProc = sort( keys( %ListProc ) );

  5. #5
    Membre Expert Avatar de dmganges
    Homme Profil pro
    Retraité. Ne recherche pas un emploi.
    Inscrit en
    Septembre 2011
    Messages
    1 425
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Retraité. Ne recherche pas un emploi.
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2011
    Messages : 1 425
    Par défaut
    Merci Jiheme44,
    C'est juste pour mon PC personnel, en fait pour m'entretenir le neurone...
    Je suis bien sous Win7.

    Oui les Keys sont uniques mais pas les Values c'est pour cela que je trie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    foreach my $Pid (sort { $ListProc{$a} cmp $ListProc{$b} } keys %ListProc )
    et désire, si possible sur la même ligne supprimer les doublons sur les Values...

    A ce jour je n'ai pas trouvé, mais peut-être mal cherché comment skype est lancé au démarrage, voir ma requête précédente :
    http://www.developpez.net/forums/d13...t-envahissant/
    Et je ne supporte pas un pgm de 60Mo en mémoire dont je ne sais ce qu'il fait...
    Mes origines ont fait de moi un parano...

    En fait ma question concerne davantage la philosophie du hash en perl...
    Ce bout de code suffit amplement :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    print "\n\nSuppression...\n";
    my $Name = "" ;
    my $OldName = "";
    foreach my $Pid (sort { $ListProc{$a} cmp $ListProc{$b} } keys %ListProc ) {
    	$Name = $ListProc{$Pid};
    	if ( $Name eq $OldName ) {
    		delete $ListProc{$Pid};
    	}
    	$OldName = $Name;
    }

  6. #6
    Membre éclairé
    Homme Profil pro
    BioInformaticien
    Inscrit en
    Décembre 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : BioInformaticien
    Secteur : Service public

    Informations forums :
    Inscription : Décembre 2012
    Messages : 49
    Par défaut
    alors skype tourne en tache de fond, comprendre il se connecte a ton compte, charge la liste de tes contacts etc... si tu veux alléger un peu ta mémoire, tu peux toujours l'empêcher de se lancer au démarrage : le mieux c'est d'executer msconfig, et de chercher dans l'onglet démarage la ligne correspondant a skype. Il me semble que pour skype tu peux même le désactiver depuis les options...

    edit... lire le message de l'auteur c'est bien

    pour ta question sur perl : tu peux inverser tes clés et tes valeurs mais avec des résultats assez aléatoires. Par contre, rien ne t'empêche de faire toi même une hash avec tes PId comme clé, qui seront par conséquent unique (puisque dans une hash)

    sinon il y a des modules qui gèrent les listes mais bon... c'est un marteau piqueur pour planter une épingle.

  7. #7
    Membre émérite Avatar de Gardyen
    Homme Profil pro
    Bio informaticien
    Inscrit en
    Août 2005
    Messages
    637
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bio informaticien

    Informations forums :
    Inscription : Août 2005
    Messages : 637
    Par défaut
    et pourquoi pas tout simplement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    my %hash;
    map {$hash{$_}++;} values %ListProc;
    my @list_of_process = keys %hash;
    sinon tu peux regarder le module List::moreutils, mais c'est un peu l'artillerie lourde

  8. #8
    Membre Expert Avatar de dmganges
    Homme Profil pro
    Retraité. Ne recherche pas un emploi.
    Inscrit en
    Septembre 2011
    Messages
    1 425
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Retraité. Ne recherche pas un emploi.
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2011
    Messages : 1 425
    Par défaut
    Merci trex7g2,
    Je suis stupéfait par la puissance de perl, que je suis loin de maintriser quand je vois, ici, ce que certains surdoués font...

    J'avais un peu honte avec ma méthode à l'ancienne
    C'est juste pour satisfaire ma curiosité quand je vois des trucs du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    delete $hash{$_} foreach grep { exists $hash{$hash{$_}} && $_ eq $hash{$hash{$_}} } keys %hash;
    Ref Philou67430 :
    http://www.developpez.net/forums/d10...h/#post5703703

  9. #9
    Membre Expert Avatar de dmganges
    Homme Profil pro
    Retraité. Ne recherche pas un emploi.
    Inscrit en
    Septembre 2011
    Messages
    1 425
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Retraité. Ne recherche pas un emploi.
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2011
    Messages : 1 425
    Par défaut
    Merci Gardyen,

    Là effectivement je viens d'apprendre quelque chose !
    Ça fonctionne, et ça ressemble à du perl
    sinon tu peux regarder le module List::moreutils, mais c'est un peu l'artillerie lourde
    MERCI pour l'info !

    Mais je ne vais pas faire avec l'artillerie...

  10. #10
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    Citation Envoyé par Gardyen Voir le message
    et pourquoi pas tout simplement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    my %hash;
    map {$hash{$_}++;} values %ListProc;
    my @list_of_process = keys %hash;
    sinon tu peux regarder le module List::moreutils, mais c'est un peu l'artillerie lourde
    Il y a encore plus simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    %ListProc = reverse %ListProc;
    Maintenant, keys %ListProc retourne une liste de process uniques.

    Ou encore :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my @list_of_process = keys %{{reverse %ListProc}};

  11. #11
    Membre éclairé
    Homme Profil pro
    BioInformaticien
    Inscrit en
    Décembre 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : BioInformaticien
    Secteur : Service public

    Informations forums :
    Inscription : Décembre 2012
    Messages : 49
    Par défaut
    le problème étant que si tu fais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my %hash_2 =reverse (reverse ( %hash)); #%hash_2 n'est pas équivalent à %hash !!
    explication : mes amis jean et jack vivent en collocation. Leurs numéros est le 01 23 45 67 89.

    j'ai une hash contenant le nom de mes amis en clés, et le numéro en valeur.

    jean -> 01..
    jack -> 01..

    si je veux faire un annuaire inversé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    my %annuaire_inverse=reverse %annuaire;
    foreach my $k (keys(%annuaire_inverse)) {
    	print "Telephone=$k prénom=$annuaire_inverse{$k}\n";
    }
    la j'aurais comme résultat en sortie :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Telephone= 01 23 45 67 89 prénom=jean
    Et le pauvre Jack est perdu dans les abysses


    Bon pour ce que tu cherches cela doit convenir je suppose

  12. #12
    Membre Expert Avatar de dmganges
    Homme Profil pro
    Retraité. Ne recherche pas un emploi.
    Inscrit en
    Septembre 2011
    Messages
    1 425
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Retraité. Ne recherche pas un emploi.
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2011
    Messages : 1 425
    Par défaut
    Un grand MERCI à tous !
    Un super GRAND MERCI à Philou67430 surprenant de simplicité et d'efficacité !!!

    Bon là je mets un résolu pour ne pas vous faire perdre davantage de temps !
    MERCI

  13. #13
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Billets dans le blog
    1
    Par défaut
    Comme les clefs d'un hash sont uniques, il suffit d'inverser les valeurs et clefs d'un hash pour dédoublonner ce hash.

    Exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    my %mois2;
    my  %mois = ("jan"=> 1, "feb"=> 2, "mar"=> 3, "Feb"=>2);
    $mois2{$value} =  $key while ($key, $value) = each %mois;
    Le hash %mois2 contient maintenant: (1 => "jan", 3=>"mar", 2=>"Feb").

    Le seul problème est que l'on ne peut pas prévoir quel sera le doublon supprimé.

  14. #14
    Membre Expert Avatar de dmganges
    Homme Profil pro
    Retraité. Ne recherche pas un emploi.
    Inscrit en
    Septembre 2011
    Messages
    1 425
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 72
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Retraité. Ne recherche pas un emploi.
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2011
    Messages : 1 425
    Par défaut
    MERCI Lolo78,

    JOLI AUSSI !!!
    Ça me convient ! vu que le(s) doublons supprimés m'importe pas du tout.

    Encore MERCI à toutes et à tous !

  15. #15
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Par défaut
    Citation Envoyé par trex7g2 Voir le message
    le problème étant que si tu fais
    ...
    Bon pour ce que tu cherches cela doit convenir je suppose
    Je n'ai pas dit que reverse permettait de régler tous les problèmes d'annuaires inversés. Je l'ai juste donné comme solution pour trouver les valeurs uniques d'un hash

    Pour ce qui est de l'annuaire inversé, je préfère fournir une solution à la proposition que j'ai faite au poste #2 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    use Data::Dumper;
    my $Proc = Win32::Process::List->new();
    my %ListProc = $Proc->GetProcesses();
    my %ListPid;
    push @{$ListPid{$ListProc{$_}}}, $_ foreach keys %ListProc;
    print Data::Dumper->Dump([\%ListPid],[qw(*listPid)]);

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [@MVC] Suppression de "value" dans RequestMapping
    Par KNIZOU dans le forum Spring Web
    Réponses: 0
    Dernier message: 29/03/2011, 14h48
  2. Suppression double dans une Grid
    Par papouuu dans le forum ASP.NET
    Réponses: 2
    Dernier message: 04/03/2011, 08h08
  3. Réponses: 5
    Dernier message: 25/02/2009, 11h02
  4. Réponses: 4
    Dernier message: 12/09/2003, 11h38
  5. Réponses: 3
    Dernier message: 12/06/2002, 21h15

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo