Page 1 sur 2
[résolu] extraire données d'une liste depuis une ou plusieurs autres
Posté : jeu. 07 févr. 2019 12:43
par fredmame
Bonjour à tous,
cela fait des années que j'utilise autoit pour des petites bricoles, essentiellement pour me faire des installations auto de programmes.
Là, je ne sais pas comment m'y prendre , d'ou mon appel aux experts si vous acceptez de m'aider :
je voudrais faire un petit programme qui me facilite la vie :
j'ai des listes contenant plusieurs centaines d'entrées à trier:
le principe est que je voudrais pouvoir filtrer depuis une liste 1.txt les données d'une liste 2.txt (ou éventuellement de la liste 1 extraire liste2 et liste 3 etc.) pour en créer une liste finale.txt mais attention, certaines entrées ne sont pas forcement dans chaque liste, je donne un exemple:
liste1.txt:
a.zip
b.zip
c.zip
d.zip
e.zip
liste2.txt:
a.zip
d.zip
g.zip
l'opération enlèverait donc a.zip et d.zip de la liste 1 (g.zip n'étant pas dans la liste 1)
liste finale créeé serait : finale.txt
b.zip
c.zip
e.zip
j'ai bien vu quelques pistes :
FileOpenDialog pour aller "browser" le disque dur et trouver le fichier
FileReadLine pour lire le contenu
il faudrait une fonction de comparaison... de lecture de variable peut etre ?
mais ca dépasse complétement mes compétences malheureusement.
Alors je m'en remets à vos pistes, conseils de fonctions....
Merci 1000 fois.
Fred.
Re: extraire données d'une liste depuis une ou plusieurs autres
Posté : jeu. 07 févr. 2019 14:17
par DimVar
Bonjour,
Tu souhaite faire du dédoublonnage entre plusieurs fichiers texte ?
Cdlt, Dimvar.
Re: extraire données d'une liste depuis une ou plusieurs autres
Posté : jeu. 07 févr. 2019 15:06
par fredmame
bonjour,
oui je pense que c'est cette piste à explorer :
dédoublonnage mais avec une subtilité que les entrées qui sont dans le fichier à "épurer" peuvent ne pas avoir de double dans l'autre et donc doivent etre gardées :
liste1: a.zip b.zip c.zip d.zip
liste 2 : a.zip b.zip g.zip
le resultat doit etre : on garde c.zip et d.zip
donc oui, on supprime les doublons a.zip b.zip mais g.zip ne doit pas apparaitre dans la liste épurée meme si il n'a pas de doublon...
qu'en pensez vous ? dédoublonnage mais avec une option particuliere de tri ?
edit:
logique de Shadok :
liste1 copiée 2 fois vers un fichier temporaire
liste2 copiée vers le fichier temporaire
on obtient ainsi :
liste1.txt:
a.zip
b.zip
c.zip
liste2.txt
b.zip
g.zip
temporaire.txt (liste1 X2) + liste2
a.zip
a.zip
b.zip
b.zip
b.zip
c.zip
c.zip
g.zip
Operation à faire :on garde juste 1 exemplaire de chaque doublon; les triples et uniques sont à supprimer.
mais bon, je ne connais pas du tout les fonctions d'autoit permettant ceci (combiner des fichiers en 1 et trier les doublons)
Re: extraire données d'une liste depuis une ou plusieurs autres
Posté : jeu. 07 févr. 2019 16:08
par DimVar
Dans ce cas, tu peux utiliser un FileReadToArray pour lire toutes les lignes, puis dans une boucle, comparer/dedoublonner.
J'essaie de te faire un truc vite fait.
Re: extraire données d'une liste depuis une ou plusieurs autres
Posté : jeu. 07 févr. 2019 16:17
par fredmame
j'en n'attendais pas tant...
je vais tout de meme explorer cette option FileReadToArray
je vais lire les definitions de cette fonction mais y'a aussi le dé doublonnage... c'est sacrement complexe
Re: extraire données d'une liste depuis une ou plusieurs autres
Posté : jeu. 07 févr. 2019 17:00
par DimVar
Voila un exemple rapide de ce qui est possible de faire avec tes deux fichiers.
Il reste à faire le dédoublonnage du fichier finale.txt. Si un expert des expressions regulieres passe par là...
Re: extraire données d'une liste depuis une ou plusieurs autres
Posté : jeu. 07 févr. 2019 17:30
par fredmame
merci beaucoup, je vais tester ca tout à l'heure.
En attendant, j'avais quand meme fait des recherches sur les expressions regulieres et j'avais noté que ces 2 operations pouvaient apporter le resultat :
en partant de ce cas:
liste1 liste2
a.zip a.zip
b.zip g.zip
c.zip
liste temporaire (on double la 1 et on ajoute la 2)
=>
a.zip
a.zip
a.zip
b.zip
b.zip
c.zip
c.zip
g.zip
opération 1:
^(.+)\r?\n(?!(.|\r?\n)*\1)
ca garde retire 1 exemplaire du doublon/triplon et enleve les uniques
il faut toujours faire un "retour de chariot" à la fin de la liste
et la liste doit etre ordonnée de maniere alphabetique (il faut donc appliquer un tri avant l'opération)
ca donne :
a.zip
a.zip
b.zip
c.zip
opération 2 :
(?-s)^(.+\R)\1+
retire les doublons (les 2 : n'en garde aucun) et garde les uniques
il faut toujours faire un "retour de chariot" à la fin de la liste
et la liste doit etre ordonnée de maniere alphabetique (il faut donc appliquer un tri avant l'opération)
ca donne :
b.zip
c.zip
ce qui est cohérent avec ce que je souhaite...
Re: extraire données d'une liste depuis une ou plusieurs autres
Posté : jeu. 07 févr. 2019 17:38
par mdanielm
Je propose une fonction qui prend 2 tableaux U et V sans doublon et qui retourne 5 tableaux:
UunionV : les éléments qui sont dans U ou dans V ou dans les deux à la fois (sans doublon)
UinterV : les éléments qui sont dans U et dans V à la fois (sans doublon)
UmoinsV : les éléments qui sont dans U et pas dans V
VmoinsU : les éléments qui sont dans V et pas dans U
UdeltaV : les éléments de U qui ne sont pas dans V ou les éléments de V qui ne sont pas dans U
Re: extraire données d'une liste depuis une ou plusieurs autres
Posté : jeu. 07 févr. 2019 18:04
par fredmame
mdanielm,
merci de votre idée, comment la mettre en forme et par rapport à la proposition précédente en quoi serait elle, à vos yeux, choisir ?
je sens bien que je nage... je n'y connais rien de tout cela.
Re: extraire données d'une liste depuis une ou plusieurs autres
Posté : jeu. 07 févr. 2019 18:44
par mdanielm
Si je considère l'exemple du début:
U=[a,b,c,d,e]
V=[a,d,g]
UmoinsV=[b,c,e] les éléments de U qui ne sont pas dans V
Dans AutoIt il y a beaucoup de fonctions Array mais celle que je vous propose n'y est pas!
Cherchez sur Internet, ou mieux, mettez vous au travail: c'est très simple je vous assure.
Re: extraire données d'une liste depuis une ou plusieurs autres
Posté : jeu. 07 févr. 2019 18:51
par fredmame
oui c'est tout à fait ca, une sorte de soustraction...
un sujet parle de quelque chose dans ce genre apparemment
https://www.autoitscript.com/forum/topi ... wo-arrays/
je vais tenter de comprendre comment tout cela fonctionne.
Merci de vos pistes
sujet à suivre, je posterai mes avancées.
Re: extraire données d'une liste depuis une ou plusieurs autres
Posté : jeu. 07 févr. 2019 20:10
par fredmame
ca avance, ca avance !!!
je pioche à droite à gauche des scripts et voila où j'en suis
il "reste" à trouver comment passer physiquement chaque fichier txt dans la variable...
à "épurer le code" aussi
#include <Array.au3>Local $a[11] = ["a.zip","b.zip","c.zip"]Local $b[12] = ["a.zip","d.zip"]Local $sda = ObjCreate("Scripting.Dictionary")Local $sdb = ObjCreate("Scripting.Dictionary")Local $sdc = ObjCreate("Scripting.Dictionary")For $i In $a $sda.Item($i)NextFor $i In $b $sdb.Item($i)NextFor $i In $a If $sdb.Exists($i) Then $sdc.Item($i)Next$asd3 = $sdc.Keys()For $i In $asd3 If $sda.Exists($i) Then $sda.Remove($i) If $sdb.Exists($i) Then $sdb.Remove($i)Next$asd1 = $sda.Keys()$asd2 = $sdb.Keys()_ArrayDisplay($asd1," liste ok " & "$asd1");_ArrayDisplay($asd2, "$asd2");_ArrayDisplay($asd3, "$asd3")$sFile = @ScriptDir & "\coucou.txt"$sString = _ArrayToString($asd1, ",", Default, Default, @CRLF)FileWrite($sFile, $sString)Sleep(1000)$sData = FileRead($sFile)MsgBox($MB_SYSTEMMODAL, "File content", $sData & @CRLF & @CRLF & "fichier crée")
Comment mettre un retour de ligne dans cette portio, au lieu de la virgule ?
merci beaucoup de votre aide
Re: extraire données d'une liste depuis une ou plusieurs autres
Posté : jeu. 07 févr. 2019 21:25
par mdanielm
Plus simplement:
#include <Array.au3>Global $U=[1,2,5,8], $V=[2,6,8,9,10]_ArrayDisplay(Moins
($U,$V))_ArrayDisplay(Moins
($V,$U))func Moins
(byref $U, byref $V) ; U, V sans doublon ; retourne U - V Local $sRet = "" for $i=0 to UBound($U)-1 if not Yest
($V, $U[$i]) Then $sRet &= $U[$i] & '|' Next ; Ote le dernier '|' $sRet = StringTrimRight($sRet, 1) ; Retourne un tableau Local $aRet = StringSplit($sRet, '|', 2) Return $aRetEndFuncfunc Yest
(byref $T, $el) ; Retourne True si $el est dans $T Local $b=false, $i=0 While not $b and $i<UBound($T) $b = ($T[$i]=$el) $i+=1 WEnd return $bEndFunc
Re: extraire données d'une liste depuis une ou plusieurs autres
Posté : sam. 09 févr. 2019 14:05
par fredmame
Bonjour à tous,
j'avance gentiment et j'y passe des heures mais comme je n'y connais rien j'ai le plaisir de voir que ca commence a etre sacrement proche de ce que je voulais faire... je ne sais pas comment apporter 2 options supplémentaires sur mon code complet qui est en bas de ce post
Merci à ceux qui savent et qui suivent mon projet en rigolant tellement c'est du patchwork de code... mais ca marche et j'en suis fier !!
1/
je voudrais pouvoir browser un fichier txt (c'est le fichier à épurer) et le passer dans la variable Local $a[11] = ["a.zip","e.zip","c.zip","d.zip","b.zip"]
la fonction ci-dessous liste bien le contenu mais si j'essaye de mettre dans la variable Local $a[11] =
je pense que ca ne formate pas comme il faut, c'est à dire que ca ne fait pas "xxx.zip , yyy.zip" etc.
Local Const $sMessage = "Appuyez sur Ctrl ou Shift pour choisir plusieurs fichiers." ; Ouvre une boîte de dialogue pour sélectionner une liste de fichier(s). Local $sFileOpenDialog = FileOpenDialog($sMessage, @WorkingDir & "\", "txt ou ini (*.ini;*.txt)", $FD_FILEMUSTEXIST + $FD_MULTISELECT)$sFileOpenDialog = StringReplace($sFileOpenDialog, "|", @CRLF)$FILE = FileOpen($sFileOpenDialog,0);$FILE = FileOpen("C:\Users\Admin\Desktop\tri par autoit\working.txt",0)$READ = FileRead($FILE)FileClose($FILE)MsgBox(0,"VOICI LE CONTENU",$READ)
2/
pouvoir utiliser le code de la fonction de fileopendialog AVEC concatenation ci-dessous pour le mettre à la place de Local $b[12] = ["d.zip","a.zip","g.zip"]
ainsi je pourrais browser 1 ou plusieurs fichiers txt (les filtres en fait) , ils seraient concaténés en 1 seul et ensuite cela passerait dans la variable Local $b[12] = de mon code général.
3/
il restera à faire une sorte de GUI pour avoir par exemple une fenetre dans laquelle on browse ou on fait un "glissé déposé" du ou des fichiers.. mais bon, ca c'est du luxe
voici mon code actuel qui marche bien mais les variables sont "statiques" c'est à dire qu'elles doivent etre incluses dans le code, ce qui n'est pas pratique
#include <Array.au3>#include <FileConstants.au3>#include <MsgBoxConstants.au3>;partie originaleLocal $a[11] = ["a.zip","e.zip","c.zip","d.zip","b.zip"]Local $b[12] = ["d.zip","a.zip","g.zip"]Local $sda = ObjCreate("Scripting.Dictionary")Local $sdb = ObjCreate("Scripting.Dictionary")Local $sdc = ObjCreate("Scripting.Dictionary")For $i In $a $sda.Item($i)NextFor $i In $b $sdb.Item($i)NextFor $i In $a If $sdb.Exists($i) Then $sdc.Item($i)Next$asd3 = $sdc.Keys()For $i In $asd3 If $sda.Exists($i) Then $sda.Remove($i) If $sdb.Exists($i) Then $sdb.Remove($i)Next$asd1 = $sda.Keys()$asd2 = $sdb.Keys()_ArrayDisplay("hide",$asd1," liste ok " & "$asd1")_Sort
($asd1)Func _Sort
(ByRef $asd1) _ArrayColInsert($asd1, 1) For $i = 0 To UBound($asd1) - 1 $asd1[$i][1] = StringRegExpReplace($asd1[$i][0], '(\d{2})\.(\d{2})\.(\d{4})', "$3$2$1") Next _ArraySort($asd1, 0, 0, 0, 1) _ArrayColDelete($asd1, 1)EndFunc ;==>_Sort;script original au cas où;_ArrayDisplay($asd2, "$asd2");_ArrayDisplay($asd3, "$asd3");là ca impose le fichier de sortie;$sFile = @ScriptDir & "\resultat_final.txt" là ca impose le fichier$sFile = FileSaveDialog("Enregistrer sous...", @ScriptDir, "Text Files (*.txt) | ini Files (*.ini) | All Files (*.*)", 18, "")If @error Then Exit$sString = _ArrayToString($asd1 , @crlf, Default, Default, @CRLF)FileWrite($sFile, $sString)
Re: extraire données d'une liste depuis une ou plusieurs autres
Posté : sam. 09 févr. 2019 18:49
par mikell
Un indice pour le 1) - qui devrait aider aussi pour le reste
Re: extraire données d'une liste depuis une ou plusieurs autres
Posté : sam. 09 févr. 2019 19:41
par fredmame
je vois bien que ca fait une chaine avec le chemin et les noms des fichiers
un tableau qui concatene les données ?
je pensais à une expression reguliere qui , à chaque ligne du fichier il puisse s'ajouter un "nom", afin que la variable puisse interpreter
un filewriteline ?
j'arrive pas, un autre indice un peu plus gros ?
je fais de mon mieux
Re: extraire données d'une liste depuis une ou plusieurs autres
Posté : sam. 09 févr. 2019 19:56
par mikell
Je n'avais pas lu le début du sujet
Apparemment tu as une liste 1 avec des noms de fichier, une liste 2 qui est une liste d'exclusion, et tu veux récupérer les noms qui sont dans 1 mais pas dans 2. Jusque là OK, ça c'est facile
Mais à quoi va servir de sélectionner plusieurs fichiers avec FileOpenDialog ?
Il faudrait sélectionner d'abord le fichier liste 1, et dans un 2ème temps le fichier liste 2, et puis s'arrêter là ake sinon ça va être ingérable (et je suis poli)
Re: extraire données d'une liste depuis une ou plusieurs autres
Posté : sam. 09 févr. 2019 20:10
par fredmame
Pas grave
c'est dans le message 14 que j'ai posté le script complet actuel
alors le but, le graal... c'est ca:
j'ai une liste contenue dans un fichier txt (la liste est faite de noms sous cette forme : a.zip b.zip etc. tout ca l'un en dessous de l'autre)
et je voudrais pouvoir effectivement avoir une ou plusieurs listes d'exclusions.
c'est pas indispensable une multi liste d'exclusion.
Je bute sur le moyen de lire le fichier .txt, et de passer toutes les données contenues dans ma fonction qui va faire le tri.
mon script actuel qui marche bien oblige a écrire physiquement la liste ainsi :
Local $a[11] = ["a.zip","e.zip","c.zip","d.zip","b.zip"]
je cherche à formater le fichier txt pour le placer dans cette variable.
Le probleme est peut etre à toruver une expresssion reguliere, je ne sais pas...
juste pour info, les listes contiennent plusieurs centaines d'entrées (meme jusqu'à 9000)
bref, il faudrait que je trouve, grace à vous , la fonction qui me list le fichier txt et me l'injecte dans ma variable en le formatant ainsi "xxx.zip", "yyy.zip" "
Re: extraire données d'une liste depuis une ou plusieurs autres
Posté : sam. 09 févr. 2019 21:19
par mikell
C'est pas bien compliqué
"Scripting.Dictionary" c'est une bonne idée, c'est infiniment plus rapide que de faire du traitement d'array
Tiens d'ailleurs, c'est le code que j'avais pondu sur le forum US que tu utilises
(mais je ne vois pas bien ce qu'une expression régulière viendrait faire là-dedans)
Donc en gros ça serait quelque chose comme ça
#Include <Array.au3>$aList = FileReadToArray
("liste1.txt") ; liste; _ArrayDisplay($aList)$aExcl = FileReadToArray
("liste2.txt") ; exclusions; construction du dictionnaire$sdList = ObjCreate("Scripting.Dictionary")For $i In $aList $sdList.Item($i)Next; suppression dans le dico des éléments présents dans les exclusionsFor $i In $aExcl $sdList.Remove($i)Next; lecture du dico nettoyé dans une array$asdList = $sdList.Keys()_ArrayDisplay($asdList)
Re: extraire données d'une liste depuis une ou plusieurs autres
Posté : sam. 09 févr. 2019 22:12
par fredmame
Merci 1000 fois mikell !!!
oui, ca doit etre ton code, je ne me souviens plus de tout ce que j'ai pu "copier-coller" tellement j'ai fait d'essais.
A toi les honneurs.
voici, le code complet qui marche , pour l'instant uniquement sur un choix d'1 fichier de départ et d'1fichier de filtre
il me reste à ajouter la fonction de concaténation si je veux combiner quelques fichiers de filtre.... et si je pousse : faire un GUI mais le resultat est là : ca marche !!
ps: ta signature "" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )" m'a été utile!
au sens propre comme figuré j'ai pompé, pompé (du code et des fichiers de codes testés et modifiés.. un vrai patchwork)
#include <Array.au3>#include <FileConstants.au3>#include <MsgBoxConstants.au3>;ouverture des fichiersLocal Const $sMessage1 = "FICHIER A FILTRER :Appuyez sur Ctrl ou Shift pour choisir plusieurs fichiers." ; Ouvre une boîte de dialogue pour sélectionner une liste de fichier(s). Local $sFileOpenDialog1 = FileOpenDialog($sMessage1, @WorkingDir & "\", "txt ou ini (*.ini;*.txt)", $FD_FILEMUSTEXIST + $FD_MULTISELECT)$sFileOpenDialog1 = StringReplace($sFileOpenDialog1, "|", @CRLF)Local Const $sMessage2 = "FICHIER A SUPPRIMER :Appuyez sur Ctrl ou Shift pour choisir plusieurs fichiers." ; Ouvre une boîte de dialogue pour sélectionner une liste de fichier(s). Local $sFileOpenDialog2 = FileOpenDialog($sMessage2, @WorkingDir & "\", "txt ou ini (*.ini;*.txt)", $FD_FILEMUSTEXIST + $FD_MULTISELECT)$sFileOpenDialog2 = StringReplace($sFileOpenDialog2, "|", @CRLF);ici le traitement des données$aList = FileReadToArray
( $sFileOpenDialog1) ; liste; _ArrayDisplay($aList)$aExcl = FileReadToArray
( $sFileOpenDialog2) ; exclusions; construction du dictionnaire$sdList = ObjCreate("Scripting.Dictionary")For $i In $aList $sdList.Item($i)Next; suppression dans le dico des éléments présents dans les exclusionsFor $i In $aExcl If $sdList.Exists($i) Then $sdList.Remove($i)Next; lecture du dico nettoyé dans une array$asdList = $sdList.Keys()_ArrayDisplay("hide",$asdList);sauvegarde du resultat$sFile = FileSaveDialog("Enregistrer sous...", @ScriptDir, "Text Files (*.txt) | ini Files (*.ini) | All Files (*.*)", 18, "")If @error Then Exit$sString = _ArrayToString($asdList , @crlf, Default, Default, @CRLF)FileWrite($sFile, $sString)