Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 07/05/2013, à 21:11

Swiss_Knight

[✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

Bonsoir,

Voilà... j'ai fait un script qui traite des images et stocke les images qui sont passées à la moulinette dans un sous-dossier "processed".

Si je relance ce script dans le même dossier, il overwrite dans le dossier "processed" les images existantes s'il retraite les mêmes fichiers du dossier parent. Or je souhaite lui coller une étape de vérification : "si le fichier traité contient le même nom que le fichier du dossier parent qui passe dans la moulinette, ne pas le traiter et passer au fichier suivant".

Je ne vois pas trop comment mettre ça en application. Peut-on mettre une condition dans un "for i in ${dossier}"; do ...
du genre : "for i in "${dossier}!=~${dossier_processed}"; do ... ?

Sachant qu'il peut y avoir énormément d'images dans les deux dossiers, et qu'elles sont volumineuses, j'aimerai pouvoir trouver le moyen le plus efficace de faire ça (i.e. le moins consommateur de temps).

Pour l'instant j'ai ce petit bout de code qui précède la boucle principale du script. Appelons-la "bouclette" :

for_string=( "${dossier}"/*.[Jj][Pp]*[Gg] )
for_processed_string=( "${dossier}/processed/"*.[Jj][Pp]*[Gg] )
let fpi=1
    for fileprocessed in "${for_processed_string[@]}"; do
        fileProcessedNames[$fpi]=`basename "${fileprocessed}" | sed -e 's/\_processed\(.jp\(e\)*g\)/\1/gI' `
        let fpi+=1
    done
bla bla
grande boucle for sur les fichiers du dossier parent; do
beaucoup de commandes
done

Avec : for_string un tableau contenant tous les noms de fichiers jpg du dossier parent.
et for_processed_string un tableau contenant tous les noms des fichiers déjà traités (donc pour les fichiers contenus dans ${for_string[@]} qui ont exactement le même nom que ceux contenus dans f${or_processed_string[@]}, ne pas les traiter et passer au suivant.)

J'imagine une sorte de vérification dans la boucle principale du script (qui commence comme ça : for i in "${for_string[@]}"; do j=`echo "${i}" | sed -e 's/\.jp\(e\)*g/\_processed.jp\1g/gI'`; do... ) : pour chaque fichier du dossier parent, vérifier d'abord s'il est aussi présent dans le dossier processed, et si oui, passer au suivant. Et si non, le traiter avec toutes les commandes qui suivent.

- Optimisation (si c'en est une...parce que c'est peut-être pas le cas) : L'idéal serait aussi de pouvoir "éliminer" les noms de fichiers dont l'existence a déjà été vérifiée afin de réduire la liste des fichiers qui resteraient à traiter au fur et à mesure que la boucle principale du script avance.... Mais peut-être que "éliminer ces fichiers" (je me comprends, c'est le principal :S ).

Et je ne sais pas s'il existe un autre moyen de trouver l'indice d'où en est la boucle que mon "truc" ci-dessus avec la petite variable "fpi" qui s'incrémente à chaque passage de cette petite bouclette...


Merci !
Beaucoup !

Dernière modification par Swiss_Knight (Le 07/05/2013, à 23:20)


xuniL

Hors ligne

#2 Le 07/05/2013, à 21:54

Haleth

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

Tu fais un tableau contenant, potentiellement, plein d'items ?!
J'ai l'impression que tu te prends la tête

Exemple:

#!/bin/bash
for i in $(find -path '*/processed' -prune -o -type f -print)
do
        [[ -f "subdir/processed/$i" ]] && echo "Bypassing $i: already processed" && continue
        echo "Processing $i.."
done

Ubuntu is an ancien African word which means "I can't configure Debian"

Because accessor & mutator are against encapsulation (one of OOP principles), good OOP-programmers do not use them. Obviously, procedural-devs do not. In fact, only ugly-devs are still using them.

Hors ligne

#3 Le 07/05/2013, à 22:11

Swiss_Knight

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

Euh... salut. Merci pour ta réponse.
Mais je ne comprends pas bien la commande là...
si je lance ça dans un terminal :
find -path '*/processed' -prune -o -type f -print

ça me sort des fichiers d'un peu partout dans mon home... même si je la lance depuis le bureau par exemple :S

or il faudrait que ça cible le dossier parent ${dossier}
et que ça scanne le sous-dossier processed de ce dossier parent et pas ailleurs.

Et puis je ne coupe pas au moins à un tableau.
C'est la seule solution élégante que j'ai trouvé pour traiter soit l'intégralité des fichiers contenus dans un dossier passé au script, soit un fichier unique passé au script. Sinon je devais faire un double de la boucle principale du script, chose que je voulais éviter à tout prix.

edit : deuxième problème : tout ceci s'inscrit dans un test sur un argument d'entrée qui laisse le choix à l'utilisateur de vérifier ou non la présence des fichiers déjà traité... en m'orientant de la sorte, je retourne vers un doublement de la boucle principale du programme.


Pour essayer d'être plus clair... voici la structure générale :

...
        a) verification="oui";; # si argument de vérification des fichiers déjà processé est actif, $verification="oui"
        d) dossier="${OPTARG}";; # le chemin du dossier OU du fichier à traiter
...

fichier="${dossier}";
if [ ! -e "${dossier}" ]; then
	echo "${dossier} does not exist, please input a valid folder or file name."
	exit
elif [ -f "${dossier}" ]; then
	dossier=`dirname "${dossier}"` 
	for_string=( "${fichier}" ) 
elif [ -d "${dossier}" ]; then
    for_string=( "${dossier}"/*.[Jj][Pp]*[Gg] )
fi

if [ "${verification}" ] && [ -d "${dossier}/processed" ]; then
    vérifier ici l'existence des fichiers déjà processés.
fi

# boucle principale du programme :
for i in "${for_string[@]}"; do j=`echo "${i}" | sed -e 's/\.jp\(e\)*g/\_processed.jp\1g/gI'`; 

moult commandes sur $i et $j.

done

Donc, si et seulement si l'option a) a été passée au script, j'aimerai faire tourner la boucle principale uniquement sur les fichiers qui n'ont pas déjà été traités (donc qui ne sont pas présent dans le sous-dossier processed).
Si l'option a) n'a pas été passée au script ; traiter tous les fichiers rencontrés sans se soucier de ceux qui auraient déjà été traités (ils seront overwrités).

Dernière modification par Swiss_Knight (Le 07/05/2013, à 22:24)


xuniL

Hors ligne

#4 Le 07/05/2013, à 22:17

Haleth

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

Par exemple:

find $dossier -path '*/processed' -prune -o -type f -print

Explication (ou voir le man):
- path '*/processed' -prune -> ne lit pas ce qu'il y a dans le repertoire processed
-o -> c'est pour dire de prendre en compte d'abord la première partie (-path .. -prune), puis la seconde
-type f -print -> pour lui dire d'afficher les fichiers de type file (donc pas les repertoires)

Tu peux rajouter, au tout debut de commande, ton $dossier

Au final, ca te sort tout les fichiers dans l'arborescence de $dossier, sans les fichiers contenus dans $dossier/processed

Une fois que t'as cette liste, tu peux, pour chacun, tester si le fichier existe dans $dossier/processed:

[[ -f "$dossier/processed/$i" ]] && echo "Bypassing $i: already processed" && continue

Donc: si le test réussi ( = si le fichier $dossier/processed/$i existe), alors on fait un continue (= on passe directement à l'entrée de boucle suivante, donc au fichier suivant)

Dernière ligne de la boucle, cette zone est exec si ton fichier n'est pas dans $dossier/processed: c'est là où tu met ton traitement;

Pour répondre à ton edit: mettons que tu remplisses une variable check à true lorsque ton user veut vérifier la présence du fichier dans $dossier/processed, et à false lorsqu'il ne le souhaite pas, tu peux donc faire ceci:

[[ "$check" == "true" ]] && [[ -f "$dossier/processed/$i" ]] && echo "Bypassing $i: already processed" && continue

Dernière modification par Haleth (Le 07/05/2013, à 22:50)


Ubuntu is an ancien African word which means "I can't configure Debian"

Because accessor & mutator are against encapsulation (one of OOP principles), good OOP-programmers do not use them. Obviously, procedural-devs do not. In fact, only ugly-devs are still using them.

Hors ligne

#5 Le 07/05/2013, à 22:42

Swiss_Knight

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

Okay merci de l'éclairage...

alors j'ai déjà un "for" qui passe en revue tous les fichiers comme tu peux le constater ci-dessus, je vais donc garder celui-ci...

j'ai intégré ça comme ça pour l'instant, ce n'est sans doute pas très propre :

if [ "${verification}" ] && [ -d "${dossier}/processed" ]; then
    for file in "${for_string[@]}"; do
        files=`basename "${file}" | sed -e 's/\.jp\(e\)*g/\_processed.jp\1g/gI'`
        [[ -f "${dossier}/processed/$files" ]] && echo "Bypassing ${file}: already processed" && continue
        echo "Processing $file.." (<-- je mets ma boucle de traitement principal ici...)
    done
fi

Le hic, c'est "que se passe-t-il si $verification n'a pas été passé au programme" ? Il ne va pas faire la boucle de traitement principale.
Si je comprends bien, je dois virer le if qui encadre tout ce bout de code que j'ai collé là et la fusionner à la tienne dans le for ? Comme ceci : [ "${verification}" ] && [ -d "${dossier}/processed" ] &&  [[ -f "${dossier}/processed/$files" ]] && echo "Bypassing ${file}: already processed" && continue

?

je commence gentiment à y voir clair...


xuniL

Hors ligne

#6 Le 07/05/2013, à 22:54

Haleth

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

Hawé, le basename est une bonne idée, ca bouche un truc que j'ai zappé;

Du coup, la solution devient la suivante:

#!/bin/bash

verification="oui" 
dossier="${OPTARG}"

if [[ "$verification" ]] && [[ ! -d "$dossier/processed" ]]
then
    #Gestion de l'erreur (exit, ou création du repertoire ..)
fi

#On met le basename dans le find (-print -> printf "%f\n") pour optimiser et simplifier
for i in $(find "$dossier" -path "$dossier/processed" -prune -o -type f -name "*.jpg" -printf "%f\n")
do
        [[ "$verification" == "oui" ]] && [[ -f "$dossier/processed/$i" ]] && echo "Bypassing $i: already processed" && continue
        echo "Processing $i.."
done

NB: tu peux mettre un regexp dans le find -name (par exemple: j[pP][gG])

Dernière modification par Haleth (Le 07/05/2013, à 22:55)


Ubuntu is an ancien African word which means "I can't configure Debian"

Because accessor & mutator are against encapsulation (one of OOP principles), good OOP-programmers do not use them. Obviously, procedural-devs do not. In fact, only ugly-devs are still using them.

Hors ligne

#7 Le 07/05/2013, à 22:55

Swiss_Knight

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

En fait, je peux directement intégré ça à la boucle principale :

for i in "${for_string[@]}"; do j=`echo "${i}" | sed -e 's/\.jp\(e\)*g/\_processed.jp\1g/gI'`;
    fileBasename=`basename "${j}"`
     [[ "${verification}" ]] && [[ -d "${dossier}/processed" ]] &&  [[ -f "${dossier}/processed/${fileBasename}" ]] && echo "Bypassing ${fileBasename}: already processed" && continue
    echo "processing ${fileBasename}"
suite du traitement
done

Bien vu, merci de ce précieux tuyau !
Je teste encore, mais ça a l'air de fonctionner correctement ! (y avait encore un truc que j'avais omis, c'est que les fichiers présents dans le dossier "processed" sont eux-mêmes suffixé de "_processed" . Par exemple : "image_schéma_09_02_processed.jpg )

EDIT : pas vu ton précédent message ; le dossier "processed", si inexistant, c'est pas grave, ça continue sans lui (il sera de toute façon créé à la fin du traitement pour y déplacer les fichiers traités). Du coup j'ai pas besoin de lancer deux fois la vérification, j'intégre directement tout ça en un coup juste après le lancement de la boucle principale : il check à chaque fois si le fichiers processed exist ; si oui, on skip, sinon, on traite.

EDIT 2 : find -iname (avec un 'i' pour ne pas tenir compte de la casse, ce dont j'ai besoin, ça évite aussi le [Jj][Pp][Gg] par contre je ne peux pas me passer du 'e' qui doit être optionnel entre le p et le g, lui aussi pouvant être en minuscule ou en majuscule. --> je ne sais pas comment rendre le 'e' optionnel, même en écrivant *.jpe?g ça va pas...

Dernière modification par Swiss_Knight (Le 07/05/2013, à 23:28)


xuniL

Hors ligne

#8 Le 08/05/2013, à 00:44

Postmortem

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

Salut,

Swiss_Knight a écrit :

EDIT 2 : find -iname (avec un 'i' pour ne pas tenir compte de la casse, ce dont j'ai besoin, ça évite aussi le [Jj][Pp][Gg] par contre je ne peux pas me passer du 'e' qui doit être optionnel entre le p et le g, lui aussi pouvant être en minuscule ou en majuscule. --> je ne sais pas comment rendre le 'e' optionnel, même en écrivant *.jpe?g ça va pas...

find "$dossier" -iregex '.*\.jpe?g'

Par contre, il ne vaut mieux pas utiliser le find avec la boucle for comme cela : for i in $(find ....)
Tu peux faire :

shopt -s nocaseglob extglob
for_string=( "$dossier"/*.jp?(e)g )
for i in "${for_string[@]}"; do .....

Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »

Hors ligne

#9 Le 08/05/2013, à 10:46

Swiss_Knight

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

Ah d'accord, donc j'étais bien parti. Merci beaucoup !

Par contre, et je ne sais pas si c'est lié à la manière dont le script est écrit, mais si je donne en argument un fichier avec le caractère étoile pour le joker, par exemple ~/path/image_09* afin de traiter toutes les images dont le nom commence par image_09 ( par exemple : image_091.jpg, image_092.jpg, ..., image_099.jpg ) et bien ça patauge dans la choucroute et il ne s'y retrouve pas...

Je me demande si c'est possible d'implémenter ceci.


xuniL

Hors ligne

#10 Le 08/05/2013, à 11:30

Postmortem

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

Si tu mets ~/path/image_09* en paramètre de ton script et que des fichiers ~/path/image_09* existent bien, ~/path/image_09* est transformé en la liste des fichiers avant l'exécution de ton script et donc, celui-ci reçoit plusieurs paramètres (~/path/image_09_1.jpg et ~/path/image_09_2.jpg par exemple)


Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »

Hors ligne

#11 Le 08/05/2013, à 11:42

Hizoka

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

comment tu fais le [✓]  ?


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#12 Le 08/05/2013, à 12:02

Haleth

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

Comme toi: tu le copies, et tu le colles smile
J'imagine


Ubuntu is an ancien African word which means "I can't configure Debian"

Because accessor & mutator are against encapsulation (one of OOP principles), good OOP-programmers do not use them. Obviously, procedural-devs do not. In fact, only ugly-devs are still using them.

Hors ligne

#13 Le 08/05/2013, à 12:03

Hizoka

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

il doit bien y avoir une combinaison de touche non ?


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#14 Le 08/05/2013, à 12:56

david96

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

Question intéressante.

En html tu peux utiliser le symbole mathématique :

&radic; 

ce qui donne : √ ça se rapproche un peu de ce dernier ✓

Je cherche encore tongue

Dernière modification par david96 (Le 08/05/2013, à 12:58)

Hors ligne

#15 Le 08/05/2013, à 13:41

Swiss_Knight

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

re salut

@postmortem :
en fait, non... malheureusement :

$ dossier="test/img*"
fichier="${dossier}"
dossier='dirname "${dossier}"'
$ for_string=( "${fichier}" )
$ echo "${for_string[@]}"
img_2012-24.jpg img_2013_04.jpg
$ echo "${#for_string[@]}"
1

il ne voit qu'une seule ligne dans le tableau, avec tous les noms de fichiers les uns derrières les autres.

@ les autres : big_smile haha vous m'avez bien fait rire ! Oui Hizoka, exactement comme tu l'as fait : un simple copier-coller.  wink

Dernière modification par Swiss_Knight (Le 08/05/2013, à 13:59)


xuniL

Hors ligne

#16 Le 08/05/2013, à 13:52

Hizoka

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

ok smile

Mais si c'est du texte, il doit être possible de créer le caractère tongue

Edit : https://fr.wikipedia.org/wiki/Coche_(typographie)
http://www.web-ncy.com/internet/formati … teres.html

echo -e '\xE2\x9C\x93'
✓
echo -e '\xe2\x9c\x94'
✔
echo -e '\xe2\x88\x9a'
√

Dernière modification par Hizoka (Le 08/05/2013, à 14:00)


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#17 Le 08/05/2013, à 13:59

Postmortem

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

Le problème est qu'en faisant :

$ dossier=test/img*
$ for_string=( "${dossier}"/*.[Jj][Pp]*[Gg] )

Le * de test/img* n'est pas utilisé comme caractère spécial mais utilisé littéralement car ${dossier} est entre guillemets. Il faudrait les enlever afin que * soit interprété. Le souci, c'est qu'en les enlevant, si tu rencontres des espaces dans les chemins générés par test/img*, le tableau for_string sera mal construit.
Pour appeler ton script, je supprimerais l'option -d et passerait les répertoires/fichiers en simple argument.
Puis boucler sur ces arguments :

#!/bin/bash
for param
do
   # Traitement de "$param"
   ...
done

À appeler ainsi :

/chemin/ton_script.sh -a "test/img"* "test/images" "test/fic 2.jpg"

Dernière modification par Postmortem (Le 08/05/2013, à 14:00)


Mot' a dit : « Un Hellfest sans Slayer, c'est comme une galette-saucisse sans saucisse ! »

Hors ligne

#18 Le 08/05/2013, à 14:00

Swiss_Knight

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

merci je regarde ta proposition... (j'ai édité le message ci-dessus; je m'étais trompé)


xuniL

Hors ligne

#19 Le 12/05/2013, à 18:24

cracolinux

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

<HS>

Sans le copier-coller, ça donne donc :

ctrl + shift + u + 2714  →   ✔

ou

ctrl + shift + u + 2713  →  ✓

</HS>


Pixup : postez vos images vite et bien - Wificheck : Aidez nous à vous aider

« Ne devenez jamais pessimiste. Un pessimiste a plus souvent raison qu'un optimiste, mais l'optimiste s'amuse plus — et aucun des deux ne peut arrêter la marche du monde. » R.Heinlein

Hors ligne

#20 Le 12/05/2013, à 18:52

Hizoka

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

compliqué les 3 touches : ctrl + shift + u

merci à toi !


KDE Neon 64bits
Tous mes softs (MKVExtractorQt, HizoSelect, HizoProgress, Qtesseract, Keneric, Services menus...) sont sur github

Hors ligne

#21 Le 13/05/2013, à 01:07

david96

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier


Excellent, merci cracolinux smile

Hors ligne

#22 Le 18/05/2013, à 13:01

cracolinux

Re : [✓] Vérifier la présence de fichiers déjà traités dans un sous dossier

smile

A vot' service !


Pixup : postez vos images vite et bien - Wificheck : Aidez nous à vous aider

« Ne devenez jamais pessimiste. Un pessimiste a plus souvent raison qu'un optimiste, mais l'optimiste s'amuse plus — et aucun des deux ne peut arrêter la marche du monde. » R.Heinlein

Hors ligne