Question
Comp. d'objets : différences de résultats (Résolu)
- Laurent Dardenne
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
sonic31 écrit:
De rienMerci beaucoup .
sonic31 écrit:
Je ne suis pas sûr que les termes \"identique (mais mort)\"soient les bons dans ce contexte.Puisque qu'il me semblait qu'un objet importé était identique (mais mort) pourquoi cela ne fonctionne pas si $ancien est importé de l'itération précédente ?
Je dirais \"Un objet valide à un instant T\"(cf. photo). Sans rentrer dans les détails car sous .NET il existe une notion de résurrection...
Ce que tu recharges est bien un objet mais c'est plutôt la représentation d'un objet, le fichier du disque.
Je suppose que l'erreur que tu avais
[code:1]
where-object {((get-childitem $rep -r $_) -eq $null
[/code:1]
est du au fait que $_ est lié à l'option -Filter, et n'a rien avoir avec un pb de persistance.
sonic31 écrit:
Là je pense que tu as un pb d'écriture des instructions du pipeA noter que comme cela la charge devient vite problèmatique. Sur un serveur correct c'est + de 5 minute de traitement pour environ 1000 fichiers .
[code:1]
..| where-object {(($ancien | foreach {$_.name}) -notcontains $_.name)-and
($_.creationtime -lt $derniercheck)}`
[/code:1]
L'imbrication de boucle dans le pipe doit y être pour beaucoup et je ne suis pas certain, là faut étudier le code dans le détails, que ce pipe soit fluide.
Je ne sais pas si le parseur réorganise ni comment il fait mais essaie de placer ce test en premier
[code:1]
$_.creationtime -lt $derniercheck
[/code:1]
et ici il me semble qu'il y ait une redondance
[code:1]
($ancien | foreach {$_.name}) -notcontains $_.name
[/code:1]
je verrais plutot ceci
[code:1]
($ancien -notcontains $_.name)
[/code:1]
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- sonic
- Auteur du sujet
- Hors Ligne
- Membre senior
-
- Messages : 65
- Remerciements reçus 0
J'ai testé la métode avec compare-object . Ca fonctionne . J'ai juste un peu de travail pour sortir que dont j'ai besoin .
Par contre : J'ai élcairci quelque chose .
J'ai $ancien créé avec :[code:1]
$ancien = get-childitem $rep -r |Where-Object {$_.PSIsContainer -eq 0}[/code:1]
et $ancien2 créé avec :[code:1]
get-childitem $rep -r |Where-Object {$_.PSIsContainer -eq 0} | export-clixml $reptrv\tutu.xml
$ancien = import-clixml $reptrv\tutu.xml
[/code:1]
J'ai donc en théorie $ancien = $ancien2 .... et bien non .
Si je fait:[code:1]
$ancien | where-object {(get-childitem $rep -r $_) -eq $null}[/code:1]
Ca fonctionne , j'ai bien le fichier qui a été supprimé , mais pour avoir le meme résultat avec $ancien2 il faut que je rajoute .name , ce qui donne:
[code:1]
$ancien2 | where-object {(get-childitem $rep -r $_.name) -eq $null}
[/code:1]
J'imagine que les différences vu avec un get-member sur les 2 variables y sont pour quelque chose sans vraiment avoir vraiment saisi . Bref ca focntionne .
Mais je n'arrive pas a faire fonctionner ce qui est dit plus haut , a savoir:
[code:1]
$ancien | where-object { $news -contains $_}
#l'inverse
$ancien | where-object { !($news -contains $_)}
#un peu de détail
$ancien | where-object { !($news -contains $_)}| %{$_.name}
[/code:1]
Je pensais avec ca pouvoir optimiser (remplacer) :
[code:1]
$ancien2 | where-object {(get-childitem $rep -r $_.name) -eq $null}
[/code:1]
Mais j'ai beau la prendre dans un sens ou son inverse la résultat n'est pas le bon . Au lieu de me sortir le ou les fichiers présent dans $ancien et abscent dans $new, ou ca me sort l'équivalent de $ancien ou rien suivant l'inverseur (!). Pourtant il me semble que:[code:1]$ancien | where-object { !($news -contains $_)}[/code:1] dit prend dans $ancien ce qui n'est pas dans $new non ?
Je vais tester (les perf) la réorganisation du pipe préconisé plus haut .<br><br>Message édité par: sonic31, à: 8/04/08 13:57
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
sonic31 écrit:
Oui mais il y a une erreur de formulation dans mon exemple, à l'origine je travaillais sur la valeur boolean. Pour clarifier mieux vaut utiliser -Contain ou -NotContains mais SANS l'opérateur notBien !
Pourtant il me semble que:[code:1]$ancien | where-object { !($news -contains $_)}[/code:1] dit prend dans $ancien ce qui n'est pas dans $new non ?
[code:1]
#Est-ce que l'objet courant est dans le tableau $news ?
$ancien | where-object { $news -contains $_}
#l'inverse
#Est-ce que l'objet courant n'est pas dans le tableau $news ?
$ancien | where-object { $news -notcontains $_}
[/code:1]
Quant au fait que $ancien et $ancien2 ne sont pas égaux c'est que export-cli ne prend pas en compte l'intégralité des propriétés, cela se voit par :
[code:1]
$Ancien #return
$Ancien2 #return
[/code:1]
Il te faut définir sur quelles propriétés se base ta vision de l'égalité, ici c'est un peu comme dans la ferme des animaux tous les objets sont égaux sauf certains plus que d'autres
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- sonic
- Auteur du sujet
- Hors Ligne
- Membre senior
-
- Messages : 65
- Remerciements reçus 0
En ce qui concerne $ancien et $ancien2 les differences que je note se vois avec
(Pour rappel [code:1]
$ancien =get-childitem $rep -r |Where-Object {$_.PSIsContainer -eq 0} [/code:1]
et $ancien 2 meme choses mais importé d'un xml (objet)qui en a recu le résultat.
)
$ancien | get-member
$ancien2 | get-member
Ou la en effet je vois bien que ne nombre de détail du coté de celui qui a été importé de l'xml sont bien moins nombreux . La liste des fichier est elle evidement la meme .
Je vien de trouver un effet de bord génant .
En effet comme pour le faire fonctionner avec l'objet importé j'ai du ajouté \".name\" a \"$_\" dans mon filtre de suppression et bien si il y a des fichiers qui portent le meme nom la suppression n'est vu que si tous ces fichiers sont suprimés . Tan qu'il en reste 1 avec le meme nom et bien il ne signale pas la disparition des autres . J'ai d'ailleur peu etre le meme probléme avec le renomage mais je traiterai ca une foi la suppression réglé .
J'hésite entre 2 bases de départ :
[code:1]$ancien | where-object {((get-childitem $rep -r $_.name) -eq $null)}[/code:1]
ou
[code:1]
$ancien | where-object {($actuel | foreach {$_.name}) -notcontains $_.name}
[/code:1] que je n'arrive plus a faire fonctionner !!!
Je pensais leur ajouter un fitre du genre :\" et ou le directoryname est egal . Pour l'instant c'est pas la joie car en fait je m'embrouille
Bref je cherche .
Connexion ou Créer un compte pour participer à la conversation.
- sonic
- Auteur du sujet
- Hors Ligne
- Membre senior
-
- Messages : 65
- Remerciements reçus 0
Connexion ou Créer un compte pour participer à la conversation.
- Laurent Dardenne
- Hors Ligne
- Modérateur
-
- Messages : 6311
- Remerciements reçus 68
sonic31 écrit:
Je te rassure tu n'es pas le seulPour l'instant c'est pas la joie car en fait je m'embrouille
...
comme je commençais à ne plus trop comprendre le problème avec -Contains, j'ai vérifié 2-3 trucs hier:
[code:1]
#Crée 2 tableaux de chaînes de caractères
$Str1=@(\"un\",\"deux\",\"trois\"«»)
$Str2=@(\"deux\",\"un\",\"trois\"«»)
$A=$Str1[0]
#Teste l'existence d'une chaîne
#Les 3 tests renvoient True
$Str2 -contains \"un\"
$Str2 -contains $A
$Str2 -contains $Str1[0]
#crée un tableau de fichier
$Fichiers= get-childitem -r |Where-Object {$_.PSIsContainer -eq 0}
#crée 2 tableaux contenant des références aux éléments du tableau de fichier
#Seul l'ordre diffère
$T=$Fichiers[0],$Fichiers[2],$Fichiers[1]
$U=$Fichiers[1],$Fichiers[0],$Fichiers[2]
#Crée une variable contenant l'objet Fichier[0]
$S=$Fichiers[0]
#Les 4 tests suivants renvoient True
# Est-ce que le tableau $T contient le Fichier[0] ?
$T -contains $Fichiers[0]
# Est-ce que le tableau $U contient le Fichier[0] ?
$U -contains $Fichiers[0]
# Est-ce que le tableau $U contient le contenu de la variable $S ?
$U -contains $S
# Est-ce que le tableau $T contient le contenu de la variable $S ?
$T -contains $S
#Si on copie le tableau par $Fichiers2=$Fichiers
#Les 4 tests précédents renvoient également True
# dans ce cas l'appel suivant renvoi true: $Fichiers.equals($Fichiers2)
# Les modifications de $Fichiers sont répercutées dans $Fichiers2 et inversement
#On crée un second tableau de fichier portant sur les mêmes informations, le file system n'a pas évolué
$Fichiers2= get-childitem -r |Where-Object {$_.PSIsContainer -eq 0}
#Crée une variable contenant l'objet Fichier2[0]
$S2=$Fichiers2[0]
# Est-ce que le tableau $T contient le contenu de la variable $S2 ?
$T -contains $S2
# False
NON !
# Est-ce que le tableau $T contient le Fichiers2[0]
$T -contains $Fichiers2[0]
# False
NON !
#On revérifie si le même objet référencé dans un autre tableau existe bien dans $T
$T -contains $Fichiers[0]
# True
OUI !
#on compare avec l'opérateur equale si les 2 objets sont bien égaux
PS G:\PS\Compare-object> $Fichiers[0] -eq $Fichiers2[0]
# False
NON :/
#Dans ce cas l'appel suivant renvoi false
$Fichiers2[0].equals($Fichier[0])
#on compare avec le cmdLet Compare-Object si les 2 objets sont égaux
compare-object $Fichiers2[0] $Fichiers[0] -includeequal
InputObject SideIndicator
Test.ps1 ==
# Oui les 2 objets sont égaux !
[/code:1]
Je pense que ce comportment est du au fait que dans le premiers exemple (chaîne de caractère) on manipule des types valeur et dans les autres des types références (des adresses).
Dans le second exemple on manipule des adresses mais elles sont tjrs identiques, dans le dernier exemple le tableau Fichiers2 occupe d'autres adresses mais avec le même contenu.
Il faut savoir que sous .NET les tests d'egalité, méthode Equals(), se basent en priorité sur des adresses et pas sur le contenu d'un objet.
Sinon on pourrait penser que la présence des opérateurs -eq -contains, la méthode equals et le cmdlet Compare-Object n'est que redondance.
Et enfin je n'ai pas confronté cette interprétation avec ton code mais jusqu'a preuve du contraire cela me semble une bonne piste
Tutoriels PowerShell
Connexion ou Créer un compte pour participer à la conversation.
- Vous êtes ici :
-
Accueil
-
forum
-
PowerShell
-
Entraide pour les débutants
- Comp. d'objets : différences de résultats (Résolu)