Operation complexe de renomage de fichiers
santiago69
Messages postés
477
Date d'inscription
Statut
Membre
Dernière intervention
-
jipicy Messages postés 40842 Date d'inscription Statut Modérateur Dernière intervention -
jipicy Messages postés 40842 Date d'inscription Statut Modérateur Dernière intervention -
Salut a tous,
J'ai besoin de renommer des fichiers en ajoutant la date a leur nom.
ex : renommer monfichier en monfichier-2008-03-05
J'ai besoin de faire ca sur tous les fichier d'un repertoire et de ses sous repertoires.
J'ai donc ecrit le script suivant :
Ca a l'air de marcher.
Maintenant, la plupart de mes dossiers contiennent les fichiers de clients windows avec des extensions qui permettent aux utilisateurs de les afficher avec l'icone correspondante.
C'est pourquoi j'aimerais dans mon script ajouter la date avant l'extension.
ex : renommer report.xls en report-2008-03-05.xls
Est ce que quelqu'un a une idee pour faire ca ?
Merci de votre aide.
Santiago
J'ai besoin de renommer des fichiers en ajoutant la date a leur nom.
ex : renommer monfichier en monfichier-2008-03-05
J'ai besoin de faire ca sur tous les fichier d'un repertoire et de ses sous repertoires.
J'ai donc ecrit le script suivant :
find * -type f -exec mv "{}" "{}-2008-05-03" \;
Ca a l'air de marcher.
Maintenant, la plupart de mes dossiers contiennent les fichiers de clients windows avec des extensions qui permettent aux utilisateurs de les afficher avec l'icone correspondante.
C'est pourquoi j'aimerais dans mon script ajouter la date avant l'extension.
ex : renommer report.xls en report-2008-03-05.xls
Est ce que quelqu'un a une idee pour faire ca ?
Merci de votre aide.
Santiago
A voir également:
- Operation complexe de renomage de fichiers
- Explorateur de fichiers - Guide
- Impossible de supprimer un fichier - Guide
- Gestionnaire de fichiers - Télécharger - Gestion de fichiers
- Renommer des fichiers en masse - Guide
- Fichiers epub - Guide
12 réponses
bonjour,
perso j'utilise Krename c'est rapide facile pas besoin de se creuser la ciboulette suffit juste de dire ce que l'on veut ecrire
a+
perso j'utilise Krename c'est rapide facile pas besoin de se creuser la ciboulette suffit juste de dire ce que l'on veut ecrire
a+
merci jeanbi pour ta reponse.
ou puis je trouver Krename ?
il fonctionne sans interface graphique ?
je n'ai que le mode text.
ou puis je trouver Krename ?
il fonctionne sans interface graphique ?
je n'ai que le mode text.
re,
desole non krename avec Kde
mais en mode text c'est niquer mais il me semble que si tu mets un $-2008-03-05 ça doit le faire
a+
desole non krename avec Kde
mais en mode text c'est niquer mais il me semble que si tu mets un $-2008-03-05 ça doit le faire
a+
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre question
Salut,
find -type f -exec bash -c \ 'DATE=$(date +%Y-%m-%d); rep=$(dirname $1); name=$(basename $1); prefix=${name%.*}; suffix=${name#*.}; mv "$1" "${rep}/${prefix}-${DATE}.${suffix}"' - {} \;;-))
Salut jipicy,
Ca a l'air grandiose ton script !
Si t'as le temps, j'aimerais en plus que tu m'eclaircisse quelques points.
Je vais essaye de comprendre ton script par zooms successifs.
1/ Nous avons d'abord l'enveloppe generale que j'utilisais moi meme juste avant :
find -type f -exec <script> \;
Rechercher les elements de type fichier (-type f) et executer <script> pour chacun d'eux.
Saurais tu m'expliquer la difference entre les commandes suivantes ?
find -type f
find . -type f
find * -type f
2/ Je suppose que la sous-partie se lit ainsi :
bash -c '<script>' - <param>
Executer <script> avec comme parametre <param>, c'est ca ?
Il y a un antislash dans ton script qui me semble errone. Il provoque une erreur dans mes tests. Me trompe je ?
J'ai essayer bash -c help mais le rendu est totalement illisible !
Faut il toujours mettre <script> entre '' ?
Comment ferait on avec plusieurs parametres ? Et s'il y a des espaces dans les parametres ?
Faudrait il ecrire bash -c '<script>' - '<param>' '<param>'
3/ Voyons maintenant le contenu de <script>
<commande1>; <commande2>; ...
Execute les commandes l'une apres l'autre.
<varname>=<value>;
Affecte <value> a la variable <varname>
$<varname>
Lit la valeur de la variable <varname>
$(dirname "<param>");
Extrait la partie chemin d'acces de <param>.
J'ai ajoute des "" dans mon script parcequ'il y avait des espaces dans certains noms de fichier.
$(basename "<param>");
Extrait la partie nom de fichier de <param>.
${<varname>%<modele>}
Supprime la plus petite partie a droite de <varname> qui ressemble a <modele> (trouve sur linux.die.net)
Dans notre cas, <modele>=.*
monfichier devient monfichier
rien ne ressemble a .* on n'enleve rien
autre fichier.doc devient autre fichier
.doc ressemble a .* on enleve .doc
fichier v1.2.xls devient fichier v1.2
.2.xls et .xls ressemblent a .* on enleve .xls (la plus petite)
${<varname>#<modele>}
Supprime la plus petite partie a gauche de <varname> qui ressemble a <modele>.
Dans notre cas, <modele>=*.
monfichier devient monfichier
rien ne ressemble a *. on n'enleve rien
autre fichier.doc devient doc
autre fichier. ressemble a *. on enleve autre fichier.
fichier v1.2.xls devient 2.xls
fichier v1. et fichier v1.2. ressemblent a *. on enleve fichier v1. (la plus petite)
Je corrigerais avec l'instruction suivante :
${<varname>##<modele>}
Supprime la plus grande partie a gauche de <varname> qui ressemble a <modele>.
Dans notre cas, <modele>=*.
monfichier devient monfichier
rien ne ressemble a *. on n'enleve rien
autre fichier.doc devient doc
autre fichier. ressemble a *. on enleve autre fichier.
fichier v1.2.xls devient xls
fichier v1. et fichier v1.2. ressemblent a *. on enleve fichier v1.2. (la plus grande)
Il nous reste toujours un probleme : s'il n'y a aucune extension
monfichier devrait devenir "" (chaine vide)
Je propose la correction suivante :
[ "$prefix" = "$name" ] || ext=${name##*.};
On ne cherche l'extension que si le prefix est different du nom complet.
Il est 01:33 du mat, je me raccroche a la devise de jipicy... Je vais le foutre dans une P****N de fenetre ce pingouin !
Imaginons le repertoire suivant :
Executons la commande suivante :
Qu'est ce qu'on obtient ?
Et la ca marche ! Jipicy je ne te dois pas seulement une ligne de script. Je te dois de m'avoir fait toucher du doigt un langage etonement perfectionne. Rien que de comprendre comment faire un if then fi m'a pris 1/2 heure et encore une autre 1/2 heure pour trouver comment l'ecrire en une seule ligne.
Voila... C'est fini...
ET NON ! HAHAHA (rire demoniaque) !
Ca n'est pas termine. Bien que tres interessant dans la proposition de Jipicy, la date a ajouter n'est pas la date du jour. Elle doit etre recuperee dans le nom du repertoire contenant les fichiers !
Le nouveau probleme est le suivant :
Partant des fichiers suivants :
Je voudrais arriver a l'arborescence suivante :
Bon ben il est 02:12. Mes paupieres tombent et la nuit porte conseil.
Alors on verra demain.
Bonne nuit a tous
Santiago
Ca a l'air grandiose ton script !
Si t'as le temps, j'aimerais en plus que tu m'eclaircisse quelques points.
Je vais essaye de comprendre ton script par zooms successifs.
1/ Nous avons d'abord l'enveloppe generale que j'utilisais moi meme juste avant :
find -type f -exec <script> \;
Rechercher les elements de type fichier (-type f) et executer <script> pour chacun d'eux.
Saurais tu m'expliquer la difference entre les commandes suivantes ?
find -type f
find . -type f
find * -type f
2/ Je suppose que la sous-partie se lit ainsi :
bash -c '<script>' - <param>
Executer <script> avec comme parametre <param>, c'est ca ?
Il y a un antislash dans ton script qui me semble errone. Il provoque une erreur dans mes tests. Me trompe je ?
J'ai essayer bash -c help mais le rendu est totalement illisible !
Faut il toujours mettre <script> entre '' ?
Comment ferait on avec plusieurs parametres ? Et s'il y a des espaces dans les parametres ?
Faudrait il ecrire bash -c '<script>' - '<param>' '<param>'
3/ Voyons maintenant le contenu de <script>
<commande1>; <commande2>; ...
Execute les commandes l'une apres l'autre.
<varname>=<value>;
Affecte <value> a la variable <varname>
$<varname>
Lit la valeur de la variable <varname>
$(dirname "<param>");
Extrait la partie chemin d'acces de <param>.
J'ai ajoute des "" dans mon script parcequ'il y avait des espaces dans certains noms de fichier.
$(basename "<param>");
Extrait la partie nom de fichier de <param>.
${<varname>%<modele>}
Supprime la plus petite partie a droite de <varname> qui ressemble a <modele> (trouve sur linux.die.net)
Dans notre cas, <modele>=.*
monfichier devient monfichier
rien ne ressemble a .* on n'enleve rien
autre fichier.doc devient autre fichier
.doc ressemble a .* on enleve .doc
fichier v1.2.xls devient fichier v1.2
.2.xls et .xls ressemblent a .* on enleve .xls (la plus petite)
${<varname>#<modele>}
Supprime la plus petite partie a gauche de <varname> qui ressemble a <modele>.
Dans notre cas, <modele>=*.
monfichier devient monfichier
rien ne ressemble a *. on n'enleve rien
autre fichier.doc devient doc
autre fichier. ressemble a *. on enleve autre fichier.
fichier v1.2.xls devient 2.xls
fichier v1. et fichier v1.2. ressemblent a *. on enleve fichier v1. (la plus petite)
Je corrigerais avec l'instruction suivante :
${<varname>##<modele>}
Supprime la plus grande partie a gauche de <varname> qui ressemble a <modele>.
Dans notre cas, <modele>=*.
monfichier devient monfichier
rien ne ressemble a *. on n'enleve rien
autre fichier.doc devient doc
autre fichier. ressemble a *. on enleve autre fichier.
fichier v1.2.xls devient xls
fichier v1. et fichier v1.2. ressemblent a *. on enleve fichier v1.2. (la plus grande)
Il nous reste toujours un probleme : s'il n'y a aucune extension
monfichier devrait devenir "" (chaine vide)
Je propose la correction suivante :
[ "$prefix" = "$name" ] || ext=${name##*.};
On ne cherche l'extension que si le prefix est different du nom complet.
Il est 01:33 du mat, je me raccroche a la devise de jipicy... Je vais le foutre dans une P****N de fenetre ce pingouin !
Imaginons le repertoire suivant :
autre fichier.doc fichier v1.2.xls monfichier myfile.
Executons la commande suivante :
find -type f -exec bash -c 'path=$(dirname "$1"); nameext=$(basename "$1"); name=${nameext%.*}; [ "$name" = "$nameext" ] || ext=.${nameext##*.}; mv "$1" "$path/$name-2008-03-06$ext";' - {} \;
Qu'est ce qu'on obtient ?
autre fichier-2008-03-06.doc fichier v1.2-2008-03-06.xls monfichier-2008-03-06 myfile-2008-03-06.
Et la ca marche ! Jipicy je ne te dois pas seulement une ligne de script. Je te dois de m'avoir fait toucher du doigt un langage etonement perfectionne. Rien que de comprendre comment faire un if then fi m'a pris 1/2 heure et encore une autre 1/2 heure pour trouver comment l'ecrire en une seule ligne.
Voila... C'est fini...
ET NON ! HAHAHA (rire demoniaque) !
Ca n'est pas termine. Bien que tres interessant dans la proposition de Jipicy, la date a ajouter n'est pas la date du jour. Elle doit etre recuperee dans le nom du repertoire contenant les fichiers !
Le nouveau probleme est le suivant :
Partant des fichiers suivants :
/home/santiago/repertoire-20071215/fichier1.txt /home/santiago/repertoire-20071215/fichier2.txt /home/santiago/repertoire-20071215/sousrep/fichier3.txt /home/santiago/repertoire-20071215/sousrep/fichier4.txt /home/santiago/repertoire-20071230/fichier1.txt /home/santiago/repertoire-20071230/fichier2.txt /home/santiago/repertoire-20071230/sousrep/fichier3.txt /home/santiago/repertoire-20071230/sousrep/fichier4.txt
Je voudrais arriver a l'arborescence suivante :
/home/santiago/repertoire/fichier1-20071215.txt /home/santiago/repertoire/fichier1-20071230.txt /home/santiago/repertoire/fichier2-20071215.txt /home/santiago/repertoire/fichier2-20071230.txt /home/santiago/repertoire/sousrep/fichier3-20071215.txt /home/santiago/repertoire/sousrep/fichier3-20071230.txt /home/santiago/repertoire/sousrep/fichier4-20071215.txt /home/santiago/repertoire/sousrep/fichier4-20071230.txt
Bon ben il est 02:12. Mes paupieres tombent et la nuit porte conseil.
Alors on verra demain.
Bonne nuit a tous
Santiago
¡Holà! :)
Bon voici un script qui vaut ce qu'il vaut, mais je l'ai testé sur ton exemple, et d'autres exemples (nom de fichiers avec expace, extension multiple, etc.) et ça semble marcher...
L'essentiel du script se joue là:
Chaque fihcier trouvé est stocké dans la variable $fichier
On va donc a chaque fois afficher la variable (echo) , lui apporter une transformation (sed), et l'executer (bash) par la commande echo ... |sed ... |bash (Je reviens pas sur les pipes (|))
L'important est biensur la transformation par sed! Et là si tu ne connais pas les RegExp, tu vas peut-être rammer.
-n on affiche rien
's#RegExp#Remplacement#p'
Le s indique qu'on va substituer RegExp par Remplacement
le p permet d'afficher la ligne.
On vas donc afficher les lignes substituées et aucune autre
((/.+/[^/]+)(-[0-9]{8})/(.+/)*([^/]+)\.([a-zA-Z0-9]+))
Les parenthèses permettent de capturer on bout d'expression pour le réutiliser par la suite
On a 6 paires de parenthèses
* (/.+/[^/]+)(-[0-9]{8})/(.+/)*([^/]+)\.([a-zA-Z0-9]+)
* /.+/[^/]+
* -[0-9]{8}
* .+/
* [^/]+
* [a-zA-Z0-9]+
la première représente le chemin et nom complet du fichier
la seconde représente le chemin jusqu'au repertoire daté (sans cette date)
la troisème représente la date (-20080205 par exemple)
la quatrième représente l'eventuel sous-répertoire (.+/)* veut dire 0 ou n fois(*) n'importe quel caractère une fois ou plus(+), suivit d'un slash
la cinquième représente le nom du fichier (n'importe quel caractère excepté un slash)
la sixieme représente l'extension
on peut donc construire la commande suivante (la paire de parenthèse un est utilisable par \1, 2 par \2 etc.)
mkdir -p {nom du repertoire sans date}/{sous-repertoire ou rien/} (on créer le repertoire si'il n'existe pas (-p permet de creer en une fois une arboressence, sans donner d'erreur si le répertoire existe, ou si le parent n'existe pas))
&& (mkdir -p réussi toujour (sauf a le faire sur un nom de fichier existant)) on enchaine
mv {fichier avec chemin } {nom du repertoire sans date}/{sous-répertoire ou rien/}{nom du fichier}{-date}.{extension}
Conseil: joue le script en enlevant le "|bash" dans un premier temps, tu veras alors l'ensemble des commandes qui auraient être jouées si tu avait le "|bash"
Ci dessous 2 exemple de la sortie du script
J'espère que je ne t'ai pas plus embrouillé qu'autre chose, il y a plein d'autre solution, et bash n'est sans doute pas le meilleur outils pour ça, mais ce court exemple aà le merite de fonctionner :o)
A plus
Bon voici un script qui vaut ce qu'il vaut, mais je l'ai testé sur ton exemple, et d'autres exemples (nom de fichiers avec expace, extension multiple, etc.) et ça semble marcher...
#!/bin/bash SOURCE=/Users/adrien/tmp_ccm IFS_ANC=$IFS IFS=' ' find $SOURCE -type f echo echo "======== DEBUT TRAITEMENT ========" echo for file in $(find $SOURCE -type f); do echo $file | sed -E -n 's#((/.+/[^/]+)(-[0-9]{8})/(.+/)*([^/]+)\.([a-zA-Z0-9]+))#mkdir -p \2/\4 \&\& mv \1 \2/\4\5\3.\6#p'|bash done echo echo "======== FIN TRAITEMENT ========" echo find $SOURCE -type f IFS=$IFS_ANCOn zap les echo, le premier find, et le dernier find qui ne sont là que pour illustrer ton exemple sans trop me casser la tête ;-)
SOURCE=/Users/adrien/tmp_ccm #Définition du repertoire source dans lequel tu vas #travailler (celui qui contient rep-date1, rep-date2, et rep) IFS_ANC=$IFS #Sauvegarde de la valeur actuelle de la variable #IFS (internal field separator) IFS=' #On n'autorise que le retour chariot ' #comme séparateur de champ IFS=$IFS_ANC #On redonne la valeur initial à la variable IFS (fin du traitement)Le séparateur de champs permet de savoir comment traiter des argument. sir le séparateur vaut <espace> que tu as un fichier "a b.txt" et un autre "c.txt" et que tu joues la commande suivante:
for fichier in *.txt; do echo $fichier doneCela te donnera le resultat suivant:
a b.txt c.txtSi le séparateur vaut "<retour chariot>" la même commande donnera cette fois:
a b.txt c.txtC'est un définition grossière de l'IFS, mais ça suffit pour notre problème.
L'essentiel du script se joue là:
for file in $(find $SOURCE -type f); do echo $file | sed -E -n 's#((/.+/[^/]+)(-[0-9]{8})/(.+/)*([^/]+)\.([a-zA-Z0-9]+))#mkdir -p \2/\4 \&\& mv \1 \2/\4\5\3.\6#p'|bash doneLe for permet de jouer la suite sur l'ensemble des fichiers (-type f) trouvé (find) dans $SOURCE
Chaque fihcier trouvé est stocké dans la variable $fichier
On va donc a chaque fois afficher la variable (echo) , lui apporter une transformation (sed), et l'executer (bash) par la commande echo ... |sed ... |bash (Je reviens pas sur les pipes (|))
L'important est biensur la transformation par sed! Et là si tu ne connais pas les RegExp, tu vas peut-être rammer.
sed -E -n 's#((/.+/[^/]+)(-[0-9]{8})/(.+/)*([^/]+)\.([a-zA-Z0-9]+))#mkdir -p \2/\4 \&\& mv \1 \2/\4\5\3.\6#p'-E interperte le motif ((/.+/[^/]+)(-[0-9]{8})/(.+/)*([^/]+)\.([a-zA-Z0-9]+)) comme une expression régulière étendue (je passe la dessus, ça permet de ne pas avoir a echapper les caractères spéciaux (+[](){}, etc.))
-n on affiche rien
's#RegExp#Remplacement#p'
Le s indique qu'on va substituer RegExp par Remplacement
le p permet d'afficher la ligne.
On vas donc afficher les lignes substituées et aucune autre
((/.+/[^/]+)(-[0-9]{8})/(.+/)*([^/]+)\.([a-zA-Z0-9]+))
Les parenthèses permettent de capturer on bout d'expression pour le réutiliser par la suite
On a 6 paires de parenthèses
* (/.+/[^/]+)(-[0-9]{8})/(.+/)*([^/]+)\.([a-zA-Z0-9]+)
* /.+/[^/]+
* -[0-9]{8}
* .+/
* [^/]+
* [a-zA-Z0-9]+
la première représente le chemin et nom complet du fichier
la seconde représente le chemin jusqu'au repertoire daté (sans cette date)
la troisème représente la date (-20080205 par exemple)
la quatrième représente l'eventuel sous-répertoire (.+/)* veut dire 0 ou n fois(*) n'importe quel caractère une fois ou plus(+), suivit d'un slash
la cinquième représente le nom du fichier (n'importe quel caractère excepté un slash)
la sixieme représente l'extension
on peut donc construire la commande suivante (la paire de parenthèse un est utilisable par \1, 2 par \2 etc.)
mkdir -p \2/\4 \&\& mv \1 \2/\4\5\3.\6ce qui se traduit par
mkdir -p {nom du repertoire sans date}/{sous-repertoire ou rien/} (on créer le repertoire si'il n'existe pas (-p permet de creer en une fois une arboressence, sans donner d'erreur si le répertoire existe, ou si le parent n'existe pas))
&& (mkdir -p réussi toujour (sauf a le faire sur un nom de fichier existant)) on enchaine
mv {fichier avec chemin } {nom du repertoire sans date}/{sous-répertoire ou rien/}{nom du fichier}{-date}.{extension}
Conseil: joue le script en enlevant le "|bash" dans un premier temps, tu veras alors l'ensemble des commandes qui auraient être jouées si tu avait le "|bash"
Ci dessous 2 exemple de la sortie du script
/Users/adrien/tmp_ccm/a a.txt /Users/adrien/tmp_ccm/inout.txt /Users/adrien/tmp_ccm/rep/test-20080111.a /Users/adrien/tmp_ccm/rep-20080112/sousrep/test.c /Users/adrien/tmp_ccm/rep-20080112/sousrep/test.java /Users/adrien/tmp_ccm/rep-20080112/test.txt /Users/adrien/tmp_ccm/rep-20080112/test.xsl /Users/adrien/tmp_ccm/rep-20080113/sousrep/test.bak /Users/adrien/tmp_ccm/rep-20080113/sousrep/test.php /Users/adrien/tmp_ccm/rep-20080113/test.doc /Users/adrien/tmp_ccm/rep-20080113/test.ppt /Users/adrien/tmp_ccm/test-2.sh /Users/adrien/tmp_ccm/test.sh ======== DEBUT TRAITEMENT ======== ======== DEBUT TRAITEMENT ======== /Users/adrien/tmp_ccm/a a.txt /Users/adrien/tmp_ccm/inout.txt /Users/adrien/tmp_ccm/rep/sousrep/test-20080112.c /Users/adrien/tmp_ccm/rep/sousrep/test-20080112.java /Users/adrien/tmp_ccm/rep/sousrep/test-20080113.bak /Users/adrien/tmp_ccm/rep/sousrep/test-20080113.php /Users/adrien/tmp_ccm/rep/test-20080111.a /Users/adrien/tmp_ccm/rep/test-20080112.txt /Users/adrien/tmp_ccm/rep/test-20080112.xsl /Users/adrien/tmp_ccm/rep/test-20080113.doc /Users/adrien/tmp_ccm/rep/test-20080113.ppt /Users/adrien/tmp_ccm/test-2.sh /Users/adrien/tmp_ccm/test.shEt avec ton exemple à toi:
/Users/adrien/tmp_ccm/repertoire-20071215/fichier1.txt /Users/adrien/tmp_ccm/repertoire-20071215/fichier2.txt /Users/adrien/tmp_ccm/repertoire-20071215/sousrep/fichier3.txt /Users/adrien/tmp_ccm/repertoire-20071215/sousrep/fichier4.txt /Users/adrien/tmp_ccm/repertoire-20071230/fichier1.txt /Users/adrien/tmp_ccm/repertoire-20071230/fichier2.txt /Users/adrien/tmp_ccm/repertoire-20071230/sousrep/fichier3.txt /Users/adrien/tmp_ccm/repertoire-20071230/sousrep/fichier4.txt ======== DEBUT TRAITEMENT ======== ======== FIN TRAITEMENT ======== /Users/adrien/tmp_ccm/repertoire/fichier1-20071215.txt /Users/adrien/tmp_ccm/repertoire/fichier1-20071230.txt /Users/adrien/tmp_ccm/repertoire/fichier2-20071215.txt /Users/adrien/tmp_ccm/repertoire/fichier2-20071230.txt /Users/adrien/tmp_ccm/repertoire/sousrep/fichier3-20071215.txt /Users/adrien/tmp_ccm/repertoire/sousrep/fichier3-20071230.txt /Users/adrien/tmp_ccm/repertoire/sousrep/fichier4-20071215.txt /Users/adrien/tmp_ccm/repertoire/sousrep/fichier4-20071230.txt
J'espère que je ne t'ai pas plus embrouillé qu'autre chose, il y a plein d'autre solution, et bash n'est sans doute pas le meilleur outils pour ça, mais ce court exemple aà le merite de fonctionner :o)
A plus
Re-
1/ Saurais tu m'expliquer la difference entre les commandes suivantes ?
find -type f
find . -type f
find * -type f
Oui, il n'y en a pas ;-))
"find" recherche par défaut dans le répertoire courant, donc qu'on ne mette rien (= depuis le répertoire courant), qu'on désigne le répertoire courant "." (= depuis le répertoire courant) ou qu'on mette un caractère générique (= depuis le répertoire courant), c'est pareil.
2/ Je suppose que la sous-partie se lit ainsi :
bash -c '<script>' - <param>
Executer <script> avec comme parametre <param>, c'est ca ?
Oui.
Il y a un antislash dans ton script qui me semble errone. Il provoque une erreur dans mes tests. Me trompe je ?
Où ça un anti-slash ???
Tu parles de "bash -c \" ? Si oui, c'est pour protéger le retour à la ligne (\n) question de lisibilité. Il est clair que si tu écris la commande sur une seule ligne, cet anti-slash est inutile ;-)
J'ai essayer bash -c help mais le rendu est totalement illisible !
Essaie plutôt "man bash" :
Faut il toujours mettre <script> entre '' ?
Oui. Si tu dois utiliser d'autres simple quote dans l'expression, il faudra les protéger ' \'...\' '.
Comment ferait on avec plusieurs parametres ?
Avec "find" il ne peut y en avoir qu'un, vu que le paramètre est la représentation de "{}".
Et s'il y a des espaces dans les parametres ?
Toujours avec "find", je pense que ça n'a pas d'importance et que l'interprétation de "{}" est transmise sous la forme " '{}' ", donc quoté ce qui doit éliminer le problème des espaces.
Faudrait il ecrire bash -c '<script>' - '<param>' '<param>'
Oui je pense. Ou avec des doubles quotes...
3/ Voyons maintenant le contenu de <script>
T'as tout bon pour tout ;-))
3.bis/ Je corrigerais avec l'instruction suivante :
${<varname>##<modele>}
Supprime la plus grande partie a gauche de <varname> qui ressemble a <modele>.
Ma solution était donnée en fonction de ton énoncé et de ce fait je ne pouvais anticiper cet éventualité, mais je vois que tu as bien rebondi et trouver la parade, chapeau bas ;-)
3.ter/ Je propose la correction suivante :
[ "$prefix" = "$name" ] || ext=${name##*.};
On ne cherche l'extension que si le prefix est different du nom complet.
Pas mieux ;-)
la date a ajouter n'est pas la date du jour.
Je ne pouvais pas savoir ;-))
Pour le reste je m'y penche dessus...
;-))
1/ Saurais tu m'expliquer la difference entre les commandes suivantes ?
find -type f
find . -type f
find * -type f
Oui, il n'y en a pas ;-))
"find" recherche par défaut dans le répertoire courant, donc qu'on ne mette rien (= depuis le répertoire courant), qu'on désigne le répertoire courant "." (= depuis le répertoire courant) ou qu'on mette un caractère générique (= depuis le répertoire courant), c'est pareil.
2/ Je suppose que la sous-partie se lit ainsi :
bash -c '<script>' - <param>
Executer <script> avec comme parametre <param>, c'est ca ?
Oui.
Il y a un antislash dans ton script qui me semble errone. Il provoque une erreur dans mes tests. Me trompe je ?
Où ça un anti-slash ???
Tu parles de "bash -c \" ? Si oui, c'est pour protéger le retour à la ligne (\n) question de lisibilité. Il est clair que si tu écris la commande sur une seule ligne, cet anti-slash est inutile ;-)
J'ai essayer bash -c help mais le rendu est totalement illisible !
Essaie plutôt "man bash" :
-c chaîne Si l'argument -c est présent, les commandes sont interprétées depuis la chaîne fournie. S'il existe d'autres arguments après la chaîne, ils sont transmis comme paramètres position- nels, en commençant par $0.;-))
Faut il toujours mettre <script> entre '' ?
Oui. Si tu dois utiliser d'autres simple quote dans l'expression, il faudra les protéger ' \'...\' '.
Comment ferait on avec plusieurs parametres ?
Avec "find" il ne peut y en avoir qu'un, vu que le paramètre est la représentation de "{}".
Et s'il y a des espaces dans les parametres ?
Toujours avec "find", je pense que ça n'a pas d'importance et que l'interprétation de "{}" est transmise sous la forme " '{}' ", donc quoté ce qui doit éliminer le problème des espaces.
Faudrait il ecrire bash -c '<script>' - '<param>' '<param>'
Oui je pense. Ou avec des doubles quotes...
3/ Voyons maintenant le contenu de <script>
T'as tout bon pour tout ;-))
3.bis/ Je corrigerais avec l'instruction suivante :
${<varname>##<modele>}
Supprime la plus grande partie a gauche de <varname> qui ressemble a <modele>.
Ma solution était donnée en fonction de ton énoncé et de ce fait je ne pouvais anticiper cet éventualité, mais je vois que tu as bien rebondi et trouver la parade, chapeau bas ;-)
3.ter/ Je propose la correction suivante :
[ "$prefix" = "$name" ] || ext=${name##*.};
On ne cherche l'extension que si le prefix est different du nom complet.
Pas mieux ;-)
la date a ajouter n'est pas la date du jour.
Je ne pouvais pas savoir ;-))
Pour le reste je m'y penche dessus...
;-))
Salut jipicy,
Merci pour tes reponses, je comprends tout de mieux en mieux.
Hola asevere,
Ton script a l'air genial et repondrait parfaitement a mes besoins s'il marchait chez moi.
En effet, si je l'execute, j'ai l'erreur suivante (autant de fois que de fichiers)
En effet, dans le descriptif, je ne trouve pas l'option -E.
J'ai essaye avec l'option -e et j'obtiens ca :
En relisant plus attentivement ton post, tu dis :
"-E interperte le motif [...] comme une expression régulière étendue..."
Et j'ai trouve, il s'agit de l'option -r chez moi.
Ensuite, j'ai essaye de comprendre les expressions regulieres. Merci wikipedia !
1) La partie avant la date ?
Pourquoi
En effet, pourquoi imposer au moins 2 slash avant de chercher la date.
De plus, afin de le generaliser, j'ai reecris ton script avec comme parametre le repertoire contenant les dossiers datés et quand je lance la commande
je voudrais qu'il isole le parametre $1 dans l'expression reguliere. Par exemple :
J'ai essaye
Mais ca ne marche pas. As tu une idee ? Je me doute qu'il faut echaper quelques caracteres, mais je ne vois pas comment.
2) L'extension ?
Je voudrais prendre en compte les cas ou il n'y a pas d'extension. Le probleme, c'est que si j'ecrit
Voila, je rebosse encore ce we sur le pb et je vous tiens au courant.
A+
Santiago
Merci pour tes reponses, je comprends tout de mieux en mieux.
Hola asevere,
Ton script a l'air genial et repondrait parfaitement a mes besoins s'il marchait chez moi.
En effet, si je l'execute, j'ai l'erreur suivante (autant de fois que de fichiers)
sed: invalid option -- E Usage: sed [OPTION]... {script-only-if-no-other-script} [input-file]...
En effet, dans le descriptif, je ne trouve pas l'option -E.
J'ai essaye avec l'option -e et j'obtiens ca :
sed: -e expression #1, char 1: unknown command: `-'
En relisant plus attentivement ton post, tu dis :
"-E interperte le motif [...] comme une expression régulière étendue..."
Et j'ai trouve, il s'agit de l'option -r chez moi.
Ensuite, j'ai essaye de comprendre les expressions regulieres. Merci wikipedia !
1) La partie avant la date ?
Pourquoi
(/.+/[^/]+)et pas
(/.+)?
En effet, pourquoi imposer au moins 2 slash avant de chercher la date.
De plus, afin de le generaliser, j'ai reecris ton script avec comme parametre le repertoire contenant les dossiers datés et quand je lance la commande
$ trierpardate /home/santiago/
je voudrais qu'il isole le parametre $1 dans l'expression reguliere. Par exemple :
/home/santiago/dossier-20080316/... < $1 >< \2 >< \3 > < \1 >
J'ai essaye
sed -r -n '#($1(.+)(-[0-9]{8})...
Mais ca ne marche pas. As tu une idee ? Je me doute qu'il faut echaper quelques caracteres, mais je ne vois pas comment.
2) L'extension ?
Je voudrais prendre en compte les cas ou il n'y a pas d'extension. Le probleme, c'est que si j'ecrit
sed -e -n 's#((/.+/[^/]+)(_[0-9]{14})/(.+/)*([^/]+)(\.[a-zA-Z0-9]+)?)#..., alors il passe tout (nom de fichier + extension eventuelle) dans \5. Je vais essaye de faire un mix avec l'algo de jipicy.
Voila, je rebosse encore ce we sur le pb et je vous tiens au courant.
A+
Santiago
Salut à tous,
essaie
lami20j
essaie
lami20j@debian:~$ find /home/lami20j/doc -type f
/home/lami20j/doc/c/fic3.xls
/home/lami20j/doc/fichier
/home/lami20j/doc/b/fic2.xls
/home/lami20j/doc/a/fic.xls
/home/lami20j/doc/a.out
/home/lami20j/doc/moyenne.c
lami20j@debian:~$ for i in $(find /home/lami20j/doc -type f);do mv -v $i "${i%%.*}-$(date +%Y-%m-%d)$(echo ${i##*..}|sed 's/.*\(\..*\)/\1/'|sed 's/^\/.*//')";done
`/home/lami20j/doc/c/fic3.xls' -> `/home/lami20j/doc/c/fic3-2008-03-16.xls'
`/home/lami20j/doc/fichier' -> `/home/lami20j/doc/fichier-2008-03-16'
`/home/lami20j/doc/b/fic2.xls' -> `/home/lami20j/doc/b/fic2-2008-03-16.xls'
`/home/lami20j/doc/a/fic.xls' -> `/home/lami20j/doc/a/fic-2008-03-16.xls'
`/home/lami20j/doc/a.out' -> `/home/lami20j/doc/a-2008-03-16.out'
`/home/lami20j/doc/moyenne.c' -> `/home/lami20j/doc/moyenne-2008-03-16.c'
lami20j@debian:~$ find /home/lami20j/doc -type f
/home/lami20j/doc/moyenne-2008-03-16.c
/home/lami20j/doc/c/fic3-2008-03-16.xls
/home/lami20j/doc/a-2008-03-16.out
/home/lami20j/doc/b/fic2-2008-03-16.xls
/home/lami20j/doc/a/fic-2008-03-16.xls
/home/lami20j/doc/fichier-2008-03-16
lami20j@debian:~$
--
lami20j
Merci lami20j mais comme explique precedement, mon probleme maintenant est d'arrive a recuperer la date dans le nom du repertoire (il ne s'agit pas de la date d'aujourd'hui).
Exemple :
======== AVANT TRAITEMENT ========
/Users/adrien/tmp_ccm/repertoire-20071215/fichier1.txt
/Users/adrien/tmp_ccm/repertoire-20071215/fichier2
/Users/adrien/tmp_ccm/repertoire-20071215/sousrep/fichier3.txt
/Users/adrien/tmp_ccm/repertoire-20071215/sousrep/fichier4.txt
/Users/adrien/tmp_ccm/repertoire-20071230/fichier1.txt
/Users/adrien/tmp_ccm/repertoire-20071230/fichier2
/Users/adrien/tmp_ccm/repertoire-20071230/sousrep/fichier3.txt
/Users/adrien/tmp_ccm/repertoire-20071230/sousrep/fichier4.txt
======== APRES TRAITEMENT ========
/Users/adrien/tmp_ccm/repertoire/fichier1-20071215.txt
/Users/adrien/tmp_ccm/repertoire/fichier1-20071230.txt
/Users/adrien/tmp_ccm/repertoire/fichier2-20071215
/Users/adrien/tmp_ccm/repertoire/fichier2-20071230
/Users/adrien/tmp_ccm/repertoire/sousrep/fichier3-20071215.txt
/Users/adrien/tmp_ccm/repertoire/sousrep/fichier3-20071230.txt
/Users/adrien/tmp_ccm/repertoire/sousrep/fichier4-20071215.txt
/Users/adrien/tmp_ccm/repertoire/sousrep/fichier4-20071230.txt
Exemple :
======== AVANT TRAITEMENT ========
/Users/adrien/tmp_ccm/repertoire-20071215/fichier1.txt
/Users/adrien/tmp_ccm/repertoire-20071215/fichier2
/Users/adrien/tmp_ccm/repertoire-20071215/sousrep/fichier3.txt
/Users/adrien/tmp_ccm/repertoire-20071215/sousrep/fichier4.txt
/Users/adrien/tmp_ccm/repertoire-20071230/fichier1.txt
/Users/adrien/tmp_ccm/repertoire-20071230/fichier2
/Users/adrien/tmp_ccm/repertoire-20071230/sousrep/fichier3.txt
/Users/adrien/tmp_ccm/repertoire-20071230/sousrep/fichier4.txt
======== APRES TRAITEMENT ========
/Users/adrien/tmp_ccm/repertoire/fichier1-20071215.txt
/Users/adrien/tmp_ccm/repertoire/fichier1-20071230.txt
/Users/adrien/tmp_ccm/repertoire/fichier2-20071215
/Users/adrien/tmp_ccm/repertoire/fichier2-20071230
/Users/adrien/tmp_ccm/repertoire/sousrep/fichier3-20071215.txt
/Users/adrien/tmp_ccm/repertoire/sousrep/fichier3-20071230.txt
/Users/adrien/tmp_ccm/repertoire/sousrep/fichier4-20071215.txt
/Users/adrien/tmp_ccm/repertoire/sousrep/fichier4-20071230.txt
Salut a tous, c'est encore moi !
@asevere,
Ta proposition me plait de plus en plus, ca a l'air vachement balese les regexp.
Mais je bloque encore sur un point :
Comment utiliser ou creer des variables globales dans le scripts genere par sed ?
J'aimerais faire un script avec la syntaxe suivante :
Et j'aimerais utiliser $1 (SOURCE) dans regexp et $2 (DESTINATION) dans script.
Est-ce possible ?
Merci a tous
Santiago
@asevere,
Ta proposition me plait de plus en plus, ca a l'air vachement balese les regexp.
Mais je bloque encore sur un point :
Comment utiliser ou creer des variables globales dans le scripts genere par sed ?
J'aimerais faire un script avec la syntaxe suivante :
$ trierpardate SOURCE DESTINATION #!/bin/bash for file in $(find $1 -type f); do echo $file | sed -r -n 's#regexp#script#p' | bash done
Et j'aimerais utiliser $1 (SOURCE) dans regexp et $2 (DESTINATION) dans script.
Est-ce possible ?
Merci a tous
Santiago
Pour ce qui concerne "sed" et les variables, voir : SED - The Stream EDitor - Part II - Le remplacement de variables
Pour faire simple il te faudrait utiliser des guillemets autour de la commande "sed" au lieu des quotes simples, mais attention aux caractères susceptibles d'être interprétés par le shell...
;-))
Pour faire simple il te faudrait utiliser des guillemets autour de la commande "sed" au lieu des quotes simples, mais attention aux caractères susceptibles d'être interprétés par le shell...
;-))