Si quelqu'un peut me montrer où je peux en savoir plus sur ce type de travail, je l'apprécierais. J'ai une certaine expérience des scripts avec php plus que tout et j'ai travaillé sur l'apprentissage de Linux (CLI du serveur Ubuntu via SSH et SFTP pour déplacer des fichiers dans et hors de ma VM).
Essayer de traiter par lots plusieurs images dans plusieurs répertoires. J'utilise imagemagick, qui fonctionne sur un fichier à la fois.
Je voudrais que cela s'exécute en commençant par le répertoire supérieur, puis faire ce travail sur tous les fichiers jpg que le script peut trouver.
pseudo code -
for all folders in the directory
open folder
check if folder "drawings" (if !exists) then {start the loop over} else :
open drawings folder
for each file in drawings
if file is a jpg
run this program on it (convert image.jpg -crop 713x470+5+3 output.jpg)
Compris ce que je devais faire en boucle, juste besoin de comprendre syntaxe de boucle . J'espère que cela aide quelqu'un d'autre qui pourrait avoir besoin de parcourir un sous-répertoire en fonction de son nom.
for dir in */
do
for subdir in $PWD/"$dir"*/
do
if [ "$subdir" == $PWD/"$dir""Drawings"*/ ]
then
for file in "$subdir"*.jpg
do
rm "$file"
done
for file in "$subdir"*.pdf
do
newName="${file/.pdf/}"
convert -density 200 "$file" -append -resize 850 -background white -flatten "$newName".jpg
done
for file in "$subdir"*.jpg
do
newName="${file/.jpg/}"
if [[ "$file" == *"insulation"* ]]
then
convert "$file" -crop 820x710+15+97 "$newName-cropped.jpg"
else
convert "$file" -crop 820x870+15+79 "$newName-cropped.jpg"
fi
done
fi
done
done
exit 0
C'est ce que j'ai trouvé
#!/bin/bash
dnames=$(for i in $(ls -d $1*/); do echo ${i}; done)
if [ "$#" -eq "1" ]; then
for dir in $dnames
do
cd $1
cd $dir
if [ -d "drawings" ]; then
cd drawings
jpgfiles=$(ls -p | grep -v / | awk '/.jp[e]?g/{print $0}')
if [ -z "$jpgfiles" ]; then
echo "Directory drawings exist in $dir but no .jpg images were found"
else
for jpgs in $jpgfiles
do
echo "found $jpgs in ${dir}drawings" #convert $jpgs -crop 713x470+5+3 output.jpg
done
fi
else
echo "Directory drawings cannot be found in $dir"
fi
done
else
echo "A full path to the directory must be given"
echo "For instance, /home/user1/Pictures/"
fi
Cela doit être exécuté avec un paramètre, dans lequel le paramètre est le chemin d'accès complet au répertoire. Par exemple, si je cherche ce dossier dessins qui peut se trouver dans un sous-répertoire de mon répertoire / home/joram /
Ce serait comme ça
myprogram /home/joram/
Le programme boucle dans / home/joram / à travers tous les répertoires qu'il contient. Ensuite, il visite chaque répertoire dans / home/joram / dans l'espoir de trouver dessins sous-dossier. Lorsque le programme trouve le dossier dessins contenant des images .jpg, les commandes sont déclenchées. Après avoir terminé les commandes, le programme continue la boucle tant que tous les répertoires sont vérifiés.
Exemple de sortie du programme:
#Directory drawings cannot be found in /home/joram/Desktop/
#Directory drawings cannot be found in /home/joram/Documents/
#Directory drawings exist in /home/joram/Downloads/ but no .jpg images were found
#Directory drawings cannot be found in /home/joram/Music/
#Directory drawings cannot be found in /home/joram/my_scripts/
#found test2.jpeg in /home/joram/Pictures/drawings
#found test.jpg in /home/joram/Pictures/drawings
#Directory drawings cannot be found in /home/joram/Public/
REMARQUE: Dans sa forme actuelle, le programme imprime simplement les fichiers .jpg qu'il a trouvés et donne également d'autres informations (aucune autre commande n'est déclenchée). De cette façon, il peut être testé avant de faire une chose réelle. Pour que le programme obtienne ce que vous voulez, supprimez la partie écho et décommentez la commande sur la ligne 16 (si c'est la commande réelle que vous souhaitez exécuter).
Des améliorations pourraient être apportées, espérons que cela vous aidera de toute façon!
L'algorithme doit-il être exactement le même ou vous souciez-vous simplement du résultat? Parce que je pense que vous pourriez créer un code beaucoup plus court et plus facile si vous utilisez find
pour parcourir le répertoire et rechercher:
find /path/to/search-root -path '*/drawings/*.jpg' -execdir convert -crop 713x470+5+3 {} output.jpg \;
Cela trouvera tous les *.jpg
fichiers qui sont (grands-) enfants de répertoires nommés drawings
et exécutez la commande convert
sur eux. Ce dernier produit un fichier output.jpg
dans le même répertoire que le fichier source. S'il y a plusieurs fichiers source dans le même répertoire, le précédent output.jpg
l'instance sera écrasée.
Si vous souhaitez que les noms de fichiers de sortie différents et "uniques" ne remplacent pas les résultats précédents, vous devrez transformer le nom du fichier de sortie d'une manière ou d'une autre. Malheureusement, find
ne peut pas faire cela, mais nous pouvons déléguer cette tâche à un shell. Il existe plusieurs façons d'y parvenir, même si je préfère généralement un tuyau à un while read
boucle car c'est moins ennuyeux que d'échapper des caractères spéciaux:
find /path/to/search-root -path '*/drawings/*.jpg' -print0 |
while IFS= read -rd '' f; do
convert -crop 713x470+5+3 "$f" "${f%.*}.output.jpg"
done
(Cela nécessite un shell prenant en charge read -d
comme Bash. Si vous avez besoin d'une alternative plus portable, veuillez le dire.)