#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,
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
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 :
√
ce qui donne : √ ça se rapproche un peu de ce dernier ✓
Je cherche encore
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 : haha vous m'avez bien fait rire ! Oui Hizoka, exactement comme tu l'as fait : un simple copier-coller.
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
Mais si c'est du texte, il doit être possible de créer le caractère
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>
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
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
A vot' service !
Hors ligne