Question
Question débutant de base qui vient de commencer
- gsa
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
- Messages : 5
- Remerciements reçus 0
je viens de me mettre au PS. J'ai acheté le livre Guide de Ref., que j'ai recu ce matin je n'en suis qu'au début (chap2).
Je joue un peu avec la commande Get-ChildItem pour essayer de me familiariser avec la syntaxe et la manipulation des propriétés.
je me suis donné le problème suivant: Faire la somme des tailles des fichiers qui commencent par J.( juste parce que je suis dans le répertoire courant et qu'il n'y a pas trop de fichier en J) et que cela permet aussi de rajouter un pipe avec le Where-Object
le tout en une seule ligne de commande bien \"pipée\" !
je pensais faire un truc du genre
count=0 # ok il y aura 2 lignes avec l'init
count+= $count+=Get-ChildItem | Where-Object {$_.Name -like \"j*\"}| extraction de la propriété Lenght
mais je n'y arrive pas.
En decomposant, je me suis rendu compte d'une chose
$count=Get-ChildItem | Where-Object {$_.Name -like \"j*\"} me donne le nombre de fichiers (ok 6)
si je veux voir lequels , je vais les afficher
Get-ChildItem | Where-Object {$_.Name -like \"j*\"}|ft name, length
si je je fais un count de cela
$count=Get-ChildItem| Where-Object {$_.Name -like \"j*\"} |ft name, length
$count vaut 10, il me compte des lignes en plus lors de l'affichage
donc je ne peux pas \"Counter\" avec un affichage, il faut donc que je récupère la propriété Length sans l'afficher.
Je suis un peu confus car pour le name on peut faire un
Get-ChildItem -name
qui équivaut à Get-ChildItem | ft name
mais pas Get-ChildItem -Length
il faut passer par Get-ChildItem | ft Length
j'ai essayé de jouer avec le propriété Lenght comme cela
$count+=(Get-ChildItem|Where-Object{$_.name -like \"j*\"}).Length
$count =6
puis
$count+=Get-ChildItem|(Where-Object{$_.name -like \"j*\"}).Length
qui n'est pas autorisé
Entre temps j'ai trouvé la commande Measure-Object, mais j'aimerai y arriver sans elle, puisque le résultat m'importe peu finalement, mais plus la facon de l'obtenir. Afin de bien comprendre les choses
je n'ai pas encore lu la partie Tableau du Chap2 , peut etre que la solution serait la. Mais la puissance du piping m'a déjà tellement impressionné que j'en demande peut etre trop ?
Merci pour vos lumières<br><br>Message édité par: gsa, à: 11/12/14 17:22
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
gsa écrit:
Ces instructions renvoient un ou plusieurs objets, $count peut donc contenir un tableau.$count=Get-ChildItem | Where-Object {$_.Name -like \"j*\"} me donne le nombre de fichiers (ok 6)
Si c'est un tableau, il possède la propriété Count, sinon il faut s'assurer de tjr recevoir un tableau, en utilisant @( instructions )
[code:1]
$Result=@( Get-ChildItem | Where-Object {$_.Name -like \"j*\"} )
$Result.Count
[/code:1]
Note : Ce qui complique un peu les choses est que cette écriture dépend de la version de PS utilisée.
gsa écrit:
Les cmdlets Format-xxx renvoient des objets spécialisés interprétés par la console lors de l'affichage.$count vaut 10, il me compte des lignes en plus lors de l'affichage
Cela a donc peut d'intérêts :
[code:1]$result=cmdlet|Format-xxx[/code:1]
Mais ceci en a un :
[code:1]
cmdlet|Format-xxx
[/code:1]
gsa écrit:
Il ne faut pas confondre le nom d'un paramètre d'un cmdlet/fonction avec un nom de propriété d'un objet.Je suis un peu confus car pour le name on peut faire un
Get-ChildItem -name
[code:1]
#renvoie la liste des paramètres du cmdlet
(get-command Get-ChildItem).Parameters
$result=Get-ChildItem $Pshome
#renvoie la liste des membres (propriétés/méthodes) d'un objet
$result|get-member
[/code:1]
gsa écrit:
Pour connaitre le nombre d'élément d'une collection (tableau d'objets), la propriété Count existe le plus souvent.Entre temps j'ai trouvé la commande Measure-Object
Tu peux effectivement l'utiliser pour calculer la somme de la propriété Length de chaque objet contenu dans ton tableau (collection d'objets).
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- gsa
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
- Messages : 5
- Remerciements reçus 0
j'ai bien tourné en rond,et puis je suis tombé sur la commande Foreach-object je me disais que c'était pil poil ce que je cherchais,
$somme=0
Get-ChildItem | Where-Object {$_.Name -like \"j*\"} |$somme+= ForEach-Object ($_.Length)
presque bon l'idée était la, il fallait trouver la syntaxe...
et voila
Get-ChildItem | Where-Object {$_.Name -like \"j*\"} | ForEach-Object {$somme+=$_.Length}
C'est tout bête, mais ce petit exercice m'a permis de comprendre plein de choses.
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
De rien.merci Laurent d'avoir pris le temps de me répondre
gsa écrit:
Cela fait partie de l'apprentissagej'ai bien tourné en rond
gsa écrit:
Désolé de te décevoir, mais 'l'idée' n'est pas là.[code:1]
$somme=0
Get-ChildItem | Where-Object {$_.Name -like \"j*\"} |$somme+= ForEach-Object ($_.Length)
[/code:1]
presque bon l'idée était la
Un pipeline, tel que celui utilisé, ne peut contenir que des commandes (cmdlet/function,etc) le gérant. Une affectation n'en fait pas partie.
Si tu as compris le principe de Where-Oobject, il 'suffit' de l'appliquer à ForEach-Object, et autres cmdlet xxx-Object.
Et comme ce n'est pas le cas et sans vouloir t'offenser, cela me laisse l'impression que 'c'est tombé en marche'.
Le tâtonnement circulaire est aussi une forme d'apprentissage.
Ceci dit, ta construction est tout à fait sensée :
[code:1]
Get-ChildItem | Name -like \"j*\" | $somme+= $_.Length
[/code:1]
Mais n'est pas reconnu par la syntaxe de Powershell.
A la lecture on sait à peu près ce qu'on veut faire, mais ainsi formulé Powershell ne sait pas comment le faire.
Autres constructions possibles :
[code:1]
$somme=0
foreach ( $File in Get-ChildItem | Where-Object {$_.Name -like \"j*\"})
{
$somme+= $File.Length
}
$Somme
$Somme=Get-ChildItem | Where-Object {$_.Name -like \"j*\"} |Measure-Object -Property Length -Sum
$Somme.Sum
[/code:1]<br><br>Message édité par: Laurent Dardenne, à: 12/12/14 17:05
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- gsa
- Auteur du sujet
- Hors Ligne
- Nouveau membre
-
- Messages : 5
- Remerciements reçus 0
C'est la que ca devient intéressant !
Car effectivement c'est tombé en marche, mais je ne comprends pas pourquoi.
Un pipeline, tel que celui utilisé, ne peut contenir que des commandes (cmdlet/function,etc) le gérant. Une affectation n'en fait pas partie.
Est-ce que l'unique raison c'est qu'un pipe ne pas contenir d'affectation ?
Si tu as compris le principe de Where-Object, il 'suffit' de l'appliquer à ForEach-Object, et autres cmdlet xxx-Object.
Et bien je ne suis pas si sur de l'avoir compris.
Mais je vais travailler sur ta solution et la décortiquer.
merci
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
On est d'accordCar effectivement c'est tombé en marche, mais je ne comprends pas pourquoi.
gsa écrit:
le principe du pipeline est d'émettre une donnée, c'est similaire à une course de relais :Est-ce que l'unique raison c'est qu'un pipe ne pas contenir d'affectation ?
\"Un relais est une course où chaque membre d'une équipe court l’un après l’autre, l'enchaînement se faisant par le « passage de témoin » \"
Si l'un des participants garde le témoin, la course n'a plus de raison d'être ( sous cette forme en tout cas).
Une affectation ne transmet pas l'information dans le pipeline.
Un pipeline est porté par le symbole '|' (Alt-Gr + 6), il faut donc que les deux, au minimum, participant du pipeline puisse y lire et y écrire.
Un cmdlet sait le faire, pas une instruction du langage, sauf dans le premier segment :
[code:1]
10|Foreach { Write-host \"Objet courant =$_\"}
#Objet courant =10
[/code:1]
Mais ceci :
[code:1]
|$somme+= ForEach-Object ($_.Length)
[/code:1]
Ne sait pas communiquer avec le pipeline ('récupérer le témoin et le passer au suivant').
Ceci dit une affectation peut récupérer le résultat d'un pipeline :
[code:1]
$Result=10|Foreach { $_ *2}
$Rresult
#20
[/code:1]
Mais ici elle n'est pas un élément constituant du pipeline, on récupère l'information, mais le pipeline n'existe plus, car il est terminé.
gsa écrit:
Il est possible d'exécuter une instruction du langage dans le pipeline, MAIS on doit utiliser un cmdlet pour cela.Et bien je ne suis pas si sur de l'avoir compris.
Celui-ci recoit un objet et peut le traiter en exécutant du code qui est défini par un bloc de script (scriptblock): '{ instructions }'
[code:1]
cmdlet -Parameter { instructions }
ForEach-Object -Process { instructions }
ForEach-Object -Process {$somme+=$_.Length}
#ou
ForEach-Object {$somme+=$_.Length}
#ou encore
#Variable de type scriptblock
$MonTraitementScriptBlock={$somme+=$_.Length}
ForEach-Object -Process $MonTraitementScriptBlock
ForEach-Object $MonTraitementScriptBlock
#Déclare une variable contenant du code
$ScriptBlock={10+3}
#Affiche le code
$ScriptBlock
#10+3
#exécute le code contenu dans la variable
&$ScriptBlock
#13
10+3
#13
[/code:1]
Le cmdlet Foreach-Object attend en paramètre du code, c'est à dire le traitement que tu veux effectuer sur le ou les objets courants recus du pipeline.
Une écriture équivalente sans usage du pipeline :
[code:1]
$somme=0
#Boucle sur tous les objets
foreach ($Item in Get-ChildItem)
{
#Test
if ($Item.Name -like \"j*\"«»)
#Code du traitement
{
Write-Warning \"objet reçu=$Item\"
$somme+=$Item.Length
}
}
[/code:1]
Voir aussi les première page de ce tutoriel .
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Entraide pour les débutants
- Question débutant de base qui vient de commencer