Vous n'êtes pas identifié(e).
Pages : 1
Ce script permet de déplacer des fichiers selon une expression régulière.
Exemple:
$ sh file-organizer.sh "^[a-cA-C]" abc
deplacera tous les fichiers depuis le dossier courant répondant à l'expression régulière vers le dossier destination.
Plus:
* si le dossier n'existe pas, il sera créé pour vous
* si les fichiers contiennent des espaces dans leur nom, le programme proposera de les remplacer par une version avec underscores.
* si le dossier n'a pas le / dans le nom il sera automatiquement insérer -> mise a jour 16-02-2014
Aperçu:
Pour mes tests je vais rassembler mes cartes cobol (jpg + rar) dans un dossier, certains de ces fichiers présentent des espaces dans leur nom.
[warlocg][linux][~/Downloads][17:32:51][user mode]
Enter command here -> ls | grep carte
carte_cobol_1.jpg
carte_cobol_2.jpg
carte cobol 3.jpg
carte cobol 4.jpg
carte_cobol_5.jpg
carte_cobol_6.jpg
carte_cobol.rar
Ceci afin de tracer le décors. A présent voici l'apercu:
[warlocg][linux][~/Downloads][17:34:58][user mode]
Enter command here -> sh organize_file.sh "^carte" cobol
le pattern ^carte va produire le résultat suivant:
carte_cobol_1.jpg
carte_cobol_2.jpg
carte cobol 3.jpg
carte cobol 4.jpg
carte_cobol_5.jpg
carte_cobol_6.jpg
carte_cobol.rar
7 fichiers trouvés.
Des fichiers contenant des espaces ont été trouvés. Ils pourraient empecher le bon fonctionnement du programme.
Voulez-vous remplacer ces fichiers ? [O/N]
o
Le programme va remplacer fichiers contenant des espaces par des underscore.
exemple: Mon fichier test.sh => Mon_fichier_test.sh
Continuer ? [O/N] o
Déplacement des fichiers au pattern ^carte vers cobol
carte_cobol_1.jpg
carte_cobol_2.jpg
carte_cobol_3.jpg
carte_cobol_4.jpg
carte_cobol_5.jpg
carte_cobol_6.jpg
carte_cobol.rar
7 fichiers déplacés.
[warlocg][linux][~/Downloads][17:36:29][user mode]
Enter command here -> ls cobol
carte_cobol_1.jpg carte_cobol_3.jpg carte_cobol_5.jpg carte_cobol.rar
carte_cobol_2.jpg carte_cobol_4.jpg carte_cobol_6.jpg
Code source
#! /bin/sh
#set -x ; #mode tracage; pour les debuggage uniquement.
#-----------------------------------------------------------------------#
#-- --#
#-- file-organizer.sh --#
#-- author WarLocG --#
#-- synthax file-organizer.sh <expression reguliere> <dossier> --#
#-- --#
#-- Sous licence GNU GPLv3. 2013-2014. --#
#-- --#
#-----------------------------------------------------------------------#
### fonctions ###
deplaceFichier()
{
if [ -z "${1}" -o -z "${2}" ]; then
echo "Au moins un des parametres est manquant. Abandon." ;
exit ;
else
if [ ! -d "${2}" ] ; then
echo "Le dossier n'existe pas, il va être créé pour vous." ;
mkdir -p ${2} ;
fi
if [ `echo ${2} | egrep "/$" | wc -l` -eq 0 ]; then
separator="/" ;
else
separator="" ;
fi
echo "Déplacement des fichiers au pattern ${1} vers ${2}$separator" ;
cpt=`expr 0` ;
for fichier in $(ls | egrep -i ${1})
do
echo $fichier ;
cpt=`expr $cpt + 1`;
mv -- $fichier ${2}$separator ;
done
echo "$cpt fichiers déplacés." ;
fi
}
remplaceFichier()
{
# suppression des espaces dans les noms
echo "Le programme va remplacer fichiers contenant des espaces par des underscore." ;
echo "exemple: Mon fichier test.sh => Mon_fichier_test.sh" ;
find . -maxdepth 1 -type f | rename 's/ /_/g' ;
}
afficheResultat()
{
echo "le pattern ${1} va produire le résultat suivant:" ;
match=`ls | egrep -i ${1} | wc -l` ;
matchEspace=`ls | egrep -i ${1} | grep ' ' | wc -l`;
ls | egrep -i ${1} ;
echo "$match fichiers trouvés." ;
if [ $matchEspace -gt 0 ]; then
echo "Des fichiers contenant des espaces ont été trouvés. Ils pourraient empecher le bon fonctionnement du programme." ;
read -p "Voulez-vous remplacer ces fichiers ? [O/N] " choix ;
if [ $choix = "o" -o $choix = "O" ]; then
remplaceFichier ;
fi
fi
read -p "Continuer ? [O/N] " choix ;
if [ $choix = "o" -o $choix = "O" ]; then
deplaceFichier ${1} ${2}
else
echo "Fin de traitement.";
exit;
fi
}
### Main ###
if [ $# -eq 2 ]; then
afficheResultat ${1} ${2} ;
else
echo "Synthaxe : ${0} <pattern> <dossier>";
echo "<pattern> expression reguliere";
echo "<dossier> dossier de destination";
echo ;
echo "file-organizer.sh sous licence GNU GPLv3 ecrit par WarLocG(C). 2013-2014." ;
fi
Mises a jour /corrections:
v0.1 : version de base
v0.2 :
* rajout des suggestions de coyotus
* rajout d'un test sur le nom de dossier ${2} s'il finit en / ou non
Propositions rejetée (temporairement):
* compteur via ": $((cpt++))" => il n'est pas passé, génère erreur "arithmetic expression: expecting primary: "cpt++""
* find avec exec => fonctionne dans le terminal mais dans le script génère une erreur "find: Paramètre manquant pour « -exec »"
Hors ligne
Intéressant, je prend
par contre je vais modifier ces passages
echo "Voulez-vous remplacer ces fichiers ? [O/N] " ;
read choix ;
echo -n "Continuer ? [O/N] " ;
read choix ;
par
read -p "Voulez-vous remplacer ces fichiers ? [O/N] " choix
read -p "Continuer ? [O/N] " choix
et pour la partie main je ferais ceci
if [ $# -eq 2 ]; then
afficheResultat $1 $2 ;
else
echo "Synthaxe : $0 <pattern> <dossier>
<pattern> expression reguliere
<dossier> dossier de destination
file-organizer.sh sous licence GNU GPLv3 ecrit par WarLocG(C). 2013-2014."
fi
Utiliser des logiciels propriétaires, c'est comme les plats préparés, on est incapable de dire les conservateurs qu'ils contiennent, on dira toujours que c'est bon, mais ça ne remplacera jamais le repas fait maison par sa maman.
]:D #! Crunchbang & Archlinux GNU/Linux User ]:D
Hors ligne
Hello !
Merci pour le partage du script Cependant, y'a quelques trucs à revoir, et le gros coté embettant dans l'histoire sera exposé à la fin.
Tout d'abord, il est préférable d'utiliser des builtin bash au maximum (moins de syscall, plus rapide, etc).
Donc :
[== Indéfini ==]
cpt=`expr $cpt + 1` ;
remplacé par
[== Indéfini ==]
: $((cpt++))
ensuite :
[== Indéfini ==]
find . -maxdepth 1 -type f | rename 's/ /_/g'
remplacé par :
[== Indéfini ==]
find . -maxdepth 1 -type f -exec rename 's/ /_/g' {} \; #pas testé mais devrait fonctionner
Enfin, j'ai cru comprendre sur IRC que tu utilisais nano. Donc pour t'éviter de taper à chaque fois ${1}, sache que les {} ne sont pas utiles dans ce cas, $1 fait tout aussi bien l'affaire
Bon, et pour revenir au gros souci ici, c'est qu'en utilisant le globbing, ton script ne sert plus à rien.
Exemple basé sur le tiens :
[== Indéfini ==]
$ ls |grep carte
carte1.jpg
carte2.jpg
carte3.jpg
carte 4 avec espace.jpg
$ mkdir dossier_test
$ set +f #activer le globbing (activé par défaut en bash)
$ mv -v carte* dossier_test/
« carte1.jpg » -> « dossier_test/carte1.jpg »
« carte2.jpg » -> « dossier_test/carte2.jpg »
« carte3.jpg » -> « dossier_test/carte3.jpg »
« carte 4 avec espace.jpg » -> « dossier_test/carte 4 avec espace.jpg »
$ ls dossier_test/
carte1.jpg carte2.jpg carte3.jpg carte 4 avec espace.jpg
Et voila, la magie opère
Hors ligne
hé bien je ne connaissais pas cette histoire de globbing, comme quoi on en apprend tout les jours.
Merci
Utiliser des logiciels propriétaires, c'est comme les plats préparés, on est incapable de dire les conservateurs qu'ils contiennent, on dira toujours que c'est bon, mais ça ne remplacera jamais le repas fait maison par sa maman.
]:D #! Crunchbang & Archlinux GNU/Linux User ]:D
Hors ligne
Merci a vous deux pour les remarques, c'est très instructif
Pour ma part je connaissait pas non plus pour le globbing, cependant je doit reconnaitre une chose, mes exemples donnés ne sont pas parlant, ce n'est pas ce que fait le script. Ce que fait le script c'est "rassemble * fichiers faisant partie du pattern $regex et tape les dans $dossier"
@IceF0x:
Vais adapter tes solutions
@NotFound:
Merci pour la dernière remarque. En donnant des exemples en : programme "^blabla" destination, je suis d accord que le blabla* aurait fait 100% l'affaire, de meme que programme "blabla$" destination aurait aisément pu etre remplacé par *blabla, l'objectif est de pouvoir par exemple faire des trucs un peu plus complexes, dont je ne sais pas si le globbing aurait passé:
exemples au pif:
programme "^[0-9]{4}(.)*\.rar$" archives_romulation_desmume
ou
programme "^(.)*([aA]yumi|[hH]amasaki)(.)*\.(mp3|ogg|wma|mkv|rbs)$" musiques_ayumi
etc.. mais je suppose que c'est aussi faisable autrement via le globbing.
Sinon pour:
find . -maxdepth 1 -type f -exec rename 's/ /_/g' {} \;
Je l ai essayé avant ma solution mais il prenait pas => find: Paramètre manquant pour « -exec »
Edit: ca fonctionne
Edit2: dans le terminal mais pas dans le script
$((cpt++))
Je vais voir ce que ca donne avec cette solution. Je suis passé par expr en fait pour evaluer une expression numérique et pour eviter qu'il concatène les caractères, avant expr je me retrouvait avec des resultats bizarre genre : 1111 fichiers déplacés
Merci pour les retours
Hors ligne
On aura droit au fichier final quand ?
Utiliser des logiciels propriétaires, c'est comme les plats préparés, on est incapable de dire les conservateurs qu'ils contiennent, on dira toujours que c'est bon, mais ça ne remplacera jamais le repas fait maison par sa maman.
]:D #! Crunchbang & Archlinux GNU/Linux User ]:D
Hors ligne
@WarLocG : Attention à ne pas oublier les : avant $((cpt++)) sinon ça va générer une erreur. C'est un petit trick bashiste à connaitre
[== Indéfini ==]
#!/bin/bash
CPT=0
echo $CPT
: $((CPT++))
echo $CPT
-----------
$ ./test
0
1
Ensuite pour le globbing y'a extglob, ie globbing étendu qui pourrait faire le job. Mais j'en suis pas sur faut que j'me renseigne mieux et que j'fasse des tests.
Cependant, je pense pas que ça puisse être aussi poussé que ton script pour le coup, surtout pour des fichiers via ton exemple :
programme "^[0-9]{4}(.)*\.rar$" archives_romulation_desmume
Hors ligne
Voici un petit retour:
pour le
: $((cpt++))
j ai ce genre d'erreur
file-organizer.sh: 31: file-organizer.sh: arithmetic expression: expecting primary: "cpt++"
la partie modifiée:
echo "Déplacement des fichiers au pattern ${1} vers ${2}" ;
cpt=$((0)) ; # cpt=0 ; génère l'erreur également
for fichier in $(ls | egrep -i ${1})
do
echo $fichier ;
: $((cpt++)) ; # la ligne 31 qui génère l'erreur ??
if [ `echo ${2} | egrep "/$" | wc -l` -eq 0 ]; then
${2} = ${2}"/" ;
fi
mv -- $fichier ${2} ;
done
echo "$cpt fichiers déplacés." ;
Je vais rester avec expr pour le moment
Hors ligne
par contre je ne comprend pas le ; il n'est pas nécessaire si les commande sont sur une ligne séparée il me semble.
Utiliser des logiciels propriétaires, c'est comme les plats préparés, on est incapable de dire les conservateurs qu'ils contiennent, on dira toujours que c'est bon, mais ça ne remplacera jamais le repas fait maison par sa maman.
]:D #! Crunchbang & Archlinux GNU/Linux User ]:D
Hors ligne
par contre je ne comprend pas le ; il n'est pas nécessaire si les commande sont sur une ligne séparée il me semble.
C'est une convention que je me donne, un héritage du C
Sinon j ai testé 2-3 trucs:
find . -maxdepth 1 -type f -exec rename 's/ /_/g' {} \;
fonctionne dans le terminal mais dans le script il me genere une erreur
si je fini par \; => find: Paramètre manquant pour « -exec »
if [ `echo ${2} | egrep "/$" | wc -l` -eq 0 ]; then
${2} = ${2}"/" ;
fi
pour l idee de mettre les / s ils sont oubliés j'ai remplacé en
deplaceFichier()
{
if [ -z "${1}" -o -z "${2}" ]; then
echo "Au moins un des parametres est manquant. Abandon." ;
exit ;
else
if [ ! -d "${2}" ] ; then
echo "Le dossier n'existe pas, il va être créé pour vous." ;
mkdir -p ${2} ;
fi
if [ `echo ${2} | egrep "/$" | wc -l` -eq 0 ]; then
separator="/" ;
else
separator="" ;
fi
echo "Déplacement des fichiers au pattern ${1} vers ${2}$separator" ;
cpt=`expr 0` ;
for fichier in $(ls | egrep -i ${1})
do
echo $fichier ;
cpt=`expr $cpt + 1`;
mv -- $fichier ${2}$separator ;
done
echo "$cpt fichiers déplacés." ;
fi
}
et sinon j'ai conservé les {} pour ${0}, ${1} et ${2}, je trouve que ca ressort mieux.
Source mis a jour - 16-02-2014:
Hors ligne
Aaah putain désolé, tu utilises /bin/sh. Pardon, j'avais même pas fait attention, j'étais parti sur un /bin/bash. Well, normal que ça ne fonctionne pas, au temps pour moi ! [pour l'histoire du : $((cpt++)) ]
Hors ligne
@notfound : y a aucun soucis
@IceF0x:
On aura droit au fichier final quand ?
ben maintenant sauf si il y a rapports de bugs ou propositions
Hors ligne
Pages : 1