web-dev-qa-db-fra.com

Comment trouver des ressources pour exécuter un serveur de script Ubuntu

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)
3
Edward S Bernstein

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
2
Edward S Bernstein

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!

1
jiipeezz

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

0
David Foerster