Question Comp. d'objets : différences de résultats (Résolu)

Plus d'informations
il y a 17 ans 11 mois #2108 par Laurent Dardenne
Salut,
sonic31 écrit:

Merci beaucoup .

De rien :)
sonic31 écrit:

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 ne suis pas sûr que les termes \"identique (mais mort)\"soient les bons dans ce contexte.
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:

A 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 .

Là je pense que tu as un pb d'écriture des instructions du pipe
[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.

Plus d'informations
il y a 17 ans 11 mois #2121 par sonic
Bien !
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.

Plus d'informations
il y a 17 ans 11 mois #2125 par Laurent Dardenne
Salut,
sonic31 écrit:

Bien !
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 ?

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 not
[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.

Plus d'informations
il y a 17 ans 11 mois #2155 par sonic
Salut .
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é \&quot;.name\&quot; a \&quot;$_\&quot; 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 :\&quot; et ou le directoryname est egal . Pour l'instant c'est pas la joie car en fait je m'embrouille :pinch: ...

Bref je cherche .

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 17 ans 11 mois #2156 par sonic
Impossible de faire focntionner toute autre métode que celle avec le get-cilditem en dur !!!!
:blink:<br><br>Message édité par: sonic31, à: 10/04/08 14:06

Connexion ou Créer un compte pour participer à la conversation.

Plus d'informations
il y a 17 ans 11 mois #2160 par Laurent Dardenne
Salut,
sonic31 écrit:

Pour l'instant c'est pas la joie car en fait je m'embrouille :pinch: ...

Je te rassure tu n'es pas le seul :lol:
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=@(\&quot;un\&quot;,\&quot;deux\&quot;,\&quot;trois\&quot;«»)
$Str2=@(\&quot;deux\&quot;,\&quot;un\&quot;,\&quot;trois\&quot;«»)
$A=$Str1[0]
#Teste l'existence d'une chaîne
#Les 3 tests renvoient True
$Str2 -contains \&quot;un\&quot;
$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&gt; $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 :P

Tutoriels PowerShell

Connexion ou Créer un compte pour participer à la conversation.

Temps de génération de la page : 0.046 secondes
Propulsé par Kunena