Mon projet
Je crée un script shell bash à exécuter à partir du terminal. Son but est d'archiver des tas de dossiers de projets. Chaque dossier fait suite à une nomenclature prescrite: [YYYY.MM.DD] - Medium - Client - Project name - details--details - JobNumber
. Par exemple: [2006.02.01] - Print - Development - Appeal I - Kids Art Show Insert - D0601-11
. Ces projets sont actuellement un dossier. Je veux les classer dans des dossiers par nom de client. Il y a 7 clients (internes), j'utilise donc le script shell suivant:
#!/bin/bash
# Go to the Completed Projects folder.
cd /Volumes/communications/Projects/Completed\ Projects/
# Find a folder with a specified string (e.g. "Academics") in its name.
# Move (not copy) the folder to its corresponding sub-folder of the Archived Projects folder. (e.g. /Academics)
for folder in *; do
if [[ -d "$folder" ]]; then
if [[ "$folder" == *Academics* ]]; then
echo "Archiving $folder to Archived Projects → Academics...";
mv "$folder" /Volumes/communications/Projects/Archived\ Projects/Academics/
fi
elif [[ "$folder" == *Admissions* ]]; then
echo "Archiving $folder to Archived Projects → Admissions...";
mv "$folder" /Volumes/communications/Projects/Archived\ Projects/Admissions/
fi
elif [[ "$folder" == *Alumni* ]]; then
echo "Archiving $folder to Archived Projects → Academics...";
mv "$folder" /Volumes/communications/Projects/Archived\ Projects/Alumni/
fi
elif [[ "$folder" == *Communications* ]]; then
echo "Archiving $folder to Archived Projects → Academics...";
mv "$folder" /Volumes/communications/Projects/Archived\ Projects/Communications/
fi
elif [[ "$folder" == *Development* ]]; then
echo "Archiving $folder to Archived Projects → Academics...";
mv "$folder" /Volumes/communications/Projects/Archived\ Projects/Development/
fi
elif [[ "$folder" == *President* ]]; then
echo "Archiving $folder to Archived Projects → Academics...";
mv "$folder" /Volumes/communications/Projects/Archived\ Projects/President/
fi
elif [[ "$folder" == *Student\ Life* ]]; then
echo "Archiving $folder to Archived Projects → Academics...";
mv "$folder" /Volumes/communications/Projects/Archived\ Projects/Student\ Life/
fi
else #Folders that don't match the pattern prompt the use to move them by hand.
echo "$folder does not have a Department name. Move it by
done
Mon problème
Mon script mal analyser et mal enregistrer un projet nommé [2006.03.01] - Print - Development - Academics and Accreditation - D0601-08
. Il faudrait lire "Universitaires" avant de passer au conditionnel pour le client "Développement". En conséquence, il s'agirait de fichiers dans "Universitaires". Et je devrais le ramasser à la main!
L'avantage de mon système
Mes collègues et moi avons scrupuleusement scrupuleusement respecté notre nomenclature (décrite ci-dessus). Je sais que le nom du client se situe entre le deuxième et le troisième tiret.
Ma question
Comment exploiter les avantages de mon système pour résoudre mon problème? Je veux que ce script ne corresponde qu'à la partie du nom de dossier qui vient après les deux premiers traits d'union et avant le troisième trait d'union, c'est-à-dire que je veux seulement que ce script recherche le "champ" Client dans le nom du dossier. Je continue de penser aux "expressions régulières" mais je ne sais pas comment les mettre en oeuvre.
Remarque: Je préfère une solution pour augmenter mon script actuel plutôt que de le remplacer. J'y suis arrivé via @patrix sur ce site et son idée a permis d'éviter certaines erreurs.
la source
*- Academics -*
?Réponses:
Il y a plusieurs façons de le faire
bash
avec vos amis (vous pouvez vraiment vous assommer en utilisantsed
ouawk
). Un moyen assez simple consiste à utilisercut
pour obtenir le nom du dossierIl
$(echo $(echo ... ))
s'agit d'une approche paresseuse pour se débarrasser de l'espace de début / fin (carcut
ne prend pas en charge les délimiteurs multi-caractères).Si vous voulez vous assommer,
sed
vous pouvez utiliserau lieu de
cut
. Cela ne fonctionne que si le nom du dossier cible ne contient pas de nom-
même.Au lieu d'une correspondance de modèle, vous pouvez également utiliser une fonction shell pour encapsuler l'essentiel de la complexité.
la source
Pourquoi ne pas utiliser awk avec l'option de séparateur de champs -F et séparer le champ par le trait d'union. Ensuite, obtenez le troisième champ.
METTRE À JOUR
J'ai mis à jour le code pour utiliser le résultat renvoyé par l'awk pour placer le dossier de destination. Cela économise beaucoup de code. Et aussi utilisé le séparateur "-" comme Ian C souligné dans les commentaires.
J'ai également ajouté / "$ folder" à la fin du déplacement pour que le dossier lui-même soit déplacé. vous pouvez changer cela si ce n'est pas ce que vous voulez en supprimant le "dossier" à la fin de la commande mv.
Vous pouvez également effectuer une vérification croisée avec un tableau des 7 noms afin que seuls les dossiers correspondants soient déplacés. (vous pouvez insérer une autre déclaration si nécessaire)
la source
awk
est certainement la voie à suivre si cela doit absolument resterbash
.' - '
lieu de'-'
Si vous pouvez apprendre bash, vous pouvez certainement apprendre une meilleure langue comme Ruby pour résoudre ce problème.
Il y a une énorme marge d'amélioration dans ce que je publie, mais voici quelques ruby de base qui effectuent votre nouvelle catégorisation à votre place. Quelques avantages de ce code Ruby par rapport à votre code bash:
client
champs et les déplace automatiquement en fonction de votre système d'archivage préféré.Et bien sûr, si vous me le demandez, il est infiniment plus lisible et extensible. Si vous pouvez apprendre le bash, Ruby est plutôt compliqué et vous constaterez que vous pouvez l’automatiser mieux que vous ne le pouvez avec bash.
J'ai essayé de rester proche de la façon dont votre bash fonctionne pour que ça ait l'air familier. Comme vous pouvez le constater, cela fait beaucoup de bruit.
la source
chmod +x <file name>
. Maintenant, tapez simplement le nom du fichier et il s'exécutera. Cette première ligne magique!#/usr/bin/env ruby
indique au système d'exploitation d'exécuter le script à l'aide de Ruby.details--details
section varie beaucoup d'un dossier à l'autre. Il comprend souvent des caractères spéciaux comme[ ] -
. @IanC.