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

Scripts/Batch Discussion :

Comment optimiser get-childitem pour ne pas parcourir tout un repertoire ? [PowerShell]


Sujet :

Scripts/Batch

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 6
    Points : 2
    Points
    2
    Par défaut Comment optimiser get-childitem pour ne pas parcourir tout un repertoire ?
    Bonjour,

    La commande ci-dessous maarche très bien:
    $NomDuPremierFichier = Get-ChildItem -path "$MonPath1" -Name | select-object -First 1

    Problème: mes répertoires contiennent enormement de fichier et le resultat est très long à sortir. Comment faire pour recuperer le nom du premier fichier de mon repertoire sans utiliser get-childitem qui scrute tout les fichiers du reperoire? J'ai deja essayé des filtres mais ça ne change rien

    Une idée?

    Merci d'avance,

    Yapooze

  2. #2
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Etant donné que Select-object parcourt la totalité de la collection, même en précisant Select -First, tu peux procéder comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Get-ChildItem -path $pwd -Name |Foreach {$F=$_;break}
    $F

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Bonjour et merci pour la réponse.

    Je n'ai pas réussi avec la syntaxe proposée car $_ semble etre nul ou alors ça pipe mal, par contre avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Foreach ($File in Get-Childitem -path $Path -Name ){break;}
    j'ai le même temps d'execution. Comme je répète cette opération pour 16*30 répertoire d'une cinquantaine de fichiers, je suis à 20secondes d’exécution dans les deux cas...

  4. #4
    Membre chevronné
    Avatar de I'm_HERE
    Homme Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 013
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 013
    Points : 1 991
    Points
    1 991
    Par défaut
    Citation Envoyé par yapooze Voir le message
    Bonjour et merci pour la réponse.

    Je n'ai pas réussi avec la syntaxe proposée car $_ semble etre nul ou alors ça pipe mal, par contre avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Foreach ($File in Get-Childitem -path $Path -Name ){break;}
    j'ai le même temps d'execution. Comme je répète cette opération pour 16*30 répertoire d'une cinquantaine de fichiers, je suis à 20secondes d’exécution dans les deux cas...
    salut,

    le code de Laurent marche bien, as-tu mis ton chemin au lieu de $pwd
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Get-ChildItem -path $Path -Name |Foreach {$F=$_;break}

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    En fait sa technique marche mais on ne peut plus rien faire derrière même un write-host, c'est pour ça que je croyais que ça ne marchait pas. Qu'est ce que je peux faire pour debloquer les commandes suivantes?

  6. #6
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par yapooze Voir le message
    En fait sa technique marche mais on ne peut plus rien faire derrière même un write-host,
    C'est vrai si on utilise le même segment de pipeline, le cas d'origine ne précisait pas d'autres instructions, cela ne fonctionne qu'en mode console...
    Citation Envoyé par yapooze Voir le message
    Qu'est ce que je peux faire pour debloquer les commandes suivantes?
    Effectivement, le break stoppe le pipeline en cours, et pas la ligne ou le segment de pipeline en cours :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $DebugPreference="Continue"
    $sb={
      write-debug "Begin"
      Get-ChildItem -path $pwd -Name |Foreach {$F=$_;break}
      $F|% {$_.ToUpper()}|Write-Host
      write-debug "End"
    }
    &$sb
    #Pas d'affichage du End
    # ni du nom de fichier
    Essayons le return (en PS V2, pas sûr en PS V1) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $sb={
      write-debug "Begin"
      Get-ChildItem -path $pwd -Name |Foreach {$F=$_;return}
      $F|% {$_.ToUpper()}|Write-Host -fore green
      write-debug "End"
    }
    &$sb
    #Affichage du End
    # ET du nom de fichier
    $DebugPreference="SilentlyContinue"

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Merci pour ta réponse, ça marche plutôt bien. Seul problème: je suis 2x plus lent qu'avant. Comme je scrute quelques répertoires vides, je vais regarder si c'est pas ça qui ralenti.

  8. #8
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par yapooze Voir le message
    Seul problème: je suis 2x plus lent qu'avant.
    On revient peut être au point de départ :/

    Dans ce cas implémente ton script autour de l'instruction foreach ( boucle classique), de mon coté je n'ai pas le temps de faire de tests...

  9. #9
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par yapooze Voir le message
    Seul problème: je suis 2x plus lent qu'avant.
    Normal, le dernier code proposé ne sert à rien

    Après qq tests une retraite stratégique s'impose, je regarderais ce WE.

  10. #10
    Rédacteur


    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    7 171
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 7 171
    Points : 15 060
    Points
    15 060
    Billets dans le blog
    1
    Par défaut
    Une première solution, basée sur cet article :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    filter Stop-Pipeline([scriptblock]$condition = {$true}) 
    {
      $_
      if (& $condition) {continue}
    }
    $result = "No result"
    $result = do {
      Get-ChildItem -path $pwd -Name| Stop-Pipeline {$true} } 
     while ($false)
    $result
    Le pb est que ce comportement, comme le précise Jeffrey Snover dans les commentaires, peut changer sans avertissement dans les prochaines versions.

    Une autre approche basée sur un runspace via la classe PowerShell (V2) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    $powershell = [System.Management.Automation.PowerShell]::Create();   
    [void]$powershell.AddScript(@"
    Get-ChildItem -path $pwd -Name|Foreach {`$_;break}
    "@)   
    $Fichier=$powershell.Invoke()
    #$powershell.InvocationStateInfo
    $powershell.Dispose()
    $Fichier
    C'est un peu plus "lourd", mais à priori ici le comportement ne devrait pas changer.

    On pourrait combiner ceci avec une fonction telle que Take-Count, ce qui permettrait de paramètrer le nb d'objet à renvoyer...

    Reste à tester si cela répond à ton besoin.

  11. #11
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Bonjour,

    Merci beaucoup pour ta réponse: la plupart des machines que je sois analyser sont en PS v1, j'ai donc essayé la premiere solution en attendant une migration en PS v2.

    je rencontre un probleme, en V1 il semble que l'affection suivante ne soit pas possible:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $result = do {
      Get-ChildItem -path $pwd -Name| Stop-Pipeline {$true} } 
     while ($false)
    En v2 ça ne pose pas de soucis, j'ai essayé pour mes machines en PS1.0
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    do {
      $result = Get-ChildItem -path $pwd -Name| Stop-Pipeline {$true} } 
     while ($false),
    mais ça me retourne une erreur.

    Si j'ai une réponse qui marche je promets de passer le sujet en RESOLU et ne plus t'embeter. Encore Merci

  12. #12
    Candidat au Club
    Profil pro
    Inscrit en
    Octobre 2010
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2010
    Messages : 6
    Points : 2
    Points
    2
    Par défaut
    Bonjour,

    Je m'en suis sorti en ignorant l'erreur en PS1.0 et avec la syntaxe suivante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    do {
       Get-ChildItem -path $pwd -Name | Stop-Pipeline {$true} | Foreach {if ($_ -ne $null){$F=$_}} 
    } 
    while ($false)
    Encore merci pour tout, je n'aurais jamais trouvé tout seul !!

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

Discussions similaires

  1. [Python 2.X] comment copier un package pour ne pas avoir à l'installer
    Par tsumey dans le forum Général Python
    Réponses: 1
    Dernier message: 25/06/2015, 08h18
  2. Comment optimiser ma vue pour avoir un scroll rapide ?
    Par uncle_bens1 dans le forum Android
    Réponses: 0
    Dernier message: 02/07/2012, 14h59
  3. Réponses: 2
    Dernier message: 26/07/2011, 09h19
  4. comment optimiser la config pour ce genre de requête absurde ?
    Par clavier12AZQSWX dans le forum Requêtes
    Réponses: 7
    Dernier message: 21/07/2011, 14h03
  5. Réponses: 6
    Dernier message: 23/02/2007, 21h20

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