OVH Cloud OVH Cloud

Appels aux Cadors de la Ligne de commande : Renommage de fichier assez complexe.

33 réponses
Avatar
pas.de.spam
Bonjour à tous,

Voilà, j'ai un problème assez complexe à résoudre et je ne pense pas
m'en sortir par la voie clicodromique.

J'ai environ 1200 dossiers contenant chacun 1 fichier (y en avait plus
avant, mais je les ai virés.

J'aimerais renommer, en une seule fois chacun des fichiers présents dans
ces dossiers, en ajoutant au dévbut du nom, les 5 premiers caractères
présent au début du nom du dossier ...

Je ne doute pas que vous allez me sortir un formule du tonnerre de Zeus,
et je vous en remercie d'avance.

Bonne Journée


--
PO.

Pour m'écrire : po_taubaty(arobas)yahoo(point)fr

10 réponses

1 2 3 4
Avatar
pas.de.spam
Patrick Stadelmann wrote:

In article <1ifb1js.qv3fph10wqr3cN%,
(Pierre-Olivier TAUBATY) wrote:

Merci, Patrick, mais ...... euh ......... je fais quoi avec ce script ?
que je suppose Apple Script.


Coller le script dans l'Editeur de Script et cliquer sur "Exécuter".

Merci, c'est simple, mais vu que je n'ai jamais ouvert AppleScript,

j'ignorais quoi faire. Comme une poule devant un bête opinel, quoi ...

Bonne Nuit.


--
PO.

Pour m'écrire : po_taubaty(arobas)yahoo(point)fr


Avatar
Eric Levenez
Le 12/04/08 22:57, dans <1ifb95b.rq60wm1j14vjhN%,
« Pierre-Olivier TAUBATY » a écrit :

Eric Levenez wrote:

Le 12/04/08 21:55, dans <480113ce$0$893$, « Martin

En bash, c'est plus court (une ligne):

for F in */* ; do B=`basename $F`; D=`dirname $F`; echo $B | grep
'^[0-9]' >/dev/null || mv $F $D/`echo ${D:0:3}$B`; done

Ou, en plus joli et plusieurs lignes

for F in */*
do
B=`basename $F`
D=`dirname $F`
echo $B | grep '^[0-9]' >/dev/null || mv $F $D/`echo ${D:0:5}$B`
done

Ceci suppose que tes noms de fichiers ne comportent pas de blancs


Oui, sinon effacement ou perte de données garantie ! Mais pourquoi donc
faire un script comme cela lors que mettre des guillemets est si facile ?


ta remarque a-'elle une incidence sur la mise en oeuvre de ce script ?


Il ne faut ni blanc, ni tabulation dans aucun nom de fichiers et de
répertoires.

Où puis-je l'utiliser ?


À priori le script devrait marcher.

Les blancs et les caractères spéciaux sont très piégeux en shell car il y a
toujours des cas où ça foire. En gardant le code d'origine (en shell il y a
toujours 36 façons de faire la même chose, alors je n'aurais pas fait comme
cela), je verrai un truc de ce genre :

for F in */*
do
B=`basename "$F"`
D=`dirname "$F"`
echo "$B" | grep -q '^[0-9]' || mv "$F" "$D/`echo ${D:0:5}$B`"
done

Et encore, je ne suis pas sûr que cela marche tout le temps...

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.



Avatar
michele
Pier-Ol : J'ai l'impression qu'il y a des mamouths qui risquent de
voler bas, mais bon, pour atteindre la Réunion, c'est pas gagné ;-)


C'est le printemps, j'ai plein d'énergie, la sève monte.
Nan, mais.

Avatar
Anonyme
Pierre-Olivier TAUBATY wrote:

Bonjour à tous,

Voilà, j'ai un problème assez complexe à résoudre et je ne pense pas
m'en sortir par la voie clicodromique.

J'ai environ 1200 dossiers contenant chacun 1 fichier (y en avait plus
avant, mais je les ai virés.

J'aimerais renommer, en une seule fois chacun des fichiers présents dans
ces dossiers, en ajoutant au dévbut du nom, les 5 premiers caractères
présent au début du nom du dossier ...

Je ne doute pas que vous allez me sortir un formule du tonnerre de Zeus,
et je vous en remercie d'avance.

Bonne Journée


Bon, j'arrive après la bataille, mais voici ma modeste contribution :

#!/bin/zsh

RepATraiter="chemin/vers/dossier"

find "$RepATraiter" -type f -print | while read ficpath
do
ficname=$(basename "$ficpath")
dirname=$(dirname "$ficpath")
dirprefix=$(basename "$dirname")
dirprefix=${dirprefix:0:5}
echo "${ficname}" |grep "^[0-9]" >/dev/null || {
mv "${ficpath}" "${dirname}/${dirprefix}${ficname}"
}
done


Explciations :
- Par rapport aux autres propositions, je me fiche de savoir où se place
le dossier contenant le fichier, et je prends le nom du dossier
contenant le fichier, pas le nom du sous-dossier du dossier courant.
(c'est utile si tes 1200 dossiers ne sont pas au même niveau)

- J'ai détaillé sur plusieurs lignes pour plus de lisibilité, ça ne le
rend pas moins performant mais beaucoup plus lisible.

- Les espaces et caractères spéciaux dans les noms de dossiers et
fichiers sont correctements traités.

- Je l'ai fait en zsh mais ça devrait marcher en bash...

- si tu le mets dans un script, tu peux remplacer "chemin/vers/dossier"
par "${1}" et tu donnes alors le dossier à traiter en paramètre du
script.

--
Anonyme ( jayce <@> mosx.org )
********* MosX.org <http://www.mosx.org/> *********
(MosX.net renaît sous le nom MosX.org...)

Avatar
come
Bonjour,

Depuis Tiger, Appel a intégré dans ses OS un merveilleux langage de
programmation qui nous vient du Japon : le langage Ruby. Il est
parfaitement adapté pour ce genre de manipulation et supporte un mode
interactif de programmation. Ca te permet de tester au fur et à mesure
tes actions pour éviter les erreurs, par exemple.

Pour le démarrer, tu ouvres un terminal dans le répertoire qui
contient les répertoires et fichiers à transformer et tu tapes la
commande "irb" (Interactive Ruby). Tu pourras quitter irb à tout
moment avec la commande "exit".

Pour l'exemple ci dessous, je considère que tes 1200 répertoires sont
au même niveau d'arborescence sinon cela ne fonctionnera pas. J'ai
recréé chez moi une arborescence de 100 répertoires "directory001" à
"directory100" avec des fichiers "fichier.dat" à l'intérieur.

Sous irb, je crée un tableau lst contenant tous ces fichiers :

irb(main):006:0> lst=Dir["*/*"]
=> ["directory001/fichier.dat", "directory002/fichier.dat",
"directory003/fichier.dat", "directory004/fichier.dat", "directory00
5/fichier.dat", "directory006/fichier.dat", "directory007/
fichier.dat", "directory008/fichier.dat", "directory009/
fichier.dat", ...

(pour un meilleur affichage j'ai tronqué la sortie du tableau)

lst contient maintenant le tableau des fichiers. Je vire tous les
fichiers dont le nom commence par des chiffres (chez moi il n'y en a
pas, mais sinon je ferais ça) :

irb(main):032:0> lst.reject!{|file| File.basename(file) =~ /^d+/}
=> ["directory001/fichier.dat", "directory002/fichier.dat",
"directory003/fichier.dat", "directory004/fichier.dat", "directory00
5/fichier.dat", "directory006/fichier.dat", "directory007/
fichier.dat", "directory008/fichier.dat", "directory009/
fichier.dat", ...

(ne pas oublier le "!" avec reject pour transformer directement le
contenu de la variable lst)

lst[0] contient le premier fichier.

irb(main):008:0> lst[0]
=> "directory001/fichier.dat"

File.basename(lst[0]) renvoit le nom du fichier

irb(main):012:0> File.basename lst[0]
=> "fichier.dat"

... et File.dirname(lst[0]) renvoit le répertoire. File.rename permet
de renommer le fichier.

irb(main):013:0> File.dirname lst[0]
=> "directory001"

si d représente un nom de répertoire :
irb(main):014:0> d=File.dirname lst[0]
=> "directory001"

Alors d[0..4] est une chaine des 5 premiers caractères de ce
répertoire :

irb(main):015:0> d[0..4]
=> "direc"

Il me suffit donc de parcourir ce tableau comme ceci pour renommer
tous les fichiers :

irb(main):024:0> for f in lst do
irb(main):025:1* File.rename f,File.dirname(f)+"/"+File.dirname(f)
[0..4]+File.basename(f)
irb(main):026:1> end

Côme

On 12 avr, 14:41, (Pierre-Olivier TAUBATY) wrote:

J'aimerais renommer, en une seule fois chacun des fichiers présents dans
ces dossiers, en ajoutant au dévbut du nom, les 5 premiers caractères
présent au début du nom du dossier ...



Avatar
yitzhak isaac goldstein
In article
,
come wrote:

Depuis Tiger, Appel a intégré dans ses OS un merveilleux langage de
programmation qui nous vient du Japon : le langage Ruby. Il est
parfaitement adapté pour ce genre de manipulation et supporte un mode
interactif de programmation. Ca te permet de tester au fur et à mesure
tes actions pour éviter les erreurs, par exemple.

Pour le démarrer, tu ouvres un terminal dans le répertoire qui
contient les répertoires et fichiers à transformer et tu tapes la
commande "irb" (Interactive Ruby). Tu pourras quitter irb à tout
moment avec la commande "exit".


Fascinant; je me coucherai moins con ce soir.

Merci pour ça.

Y.
--
yitzhak
mac mini 1,83 ghz | mac os x 10.4.11

Avatar
Eric Levenez
Le 15/04/08 10:07, dans <1iffn40.1i2tw6y1nzio3kN%, « Jayce
Piel » a écrit :

#!/bin/zsh

RepATraiter="chemin/vers/dossier"

find "$RepATraiter" -type f -print | while read ficpath
do
ficname=$(basename "$ficpath")
dirname=$(dirname "$ficpath")
dirprefix=$(basename "$dirname")
dirprefix=${dirprefix:0:5}
echo "${ficname}" |grep "^[0-9]" >/dev/null || {
mv "${ficpath}" "${dirname}/${dirprefix}${ficname}"
}
done


À la place du "grep >/dev/null", un "grep -q" est plus joli, non ?

Je pense qu'il va y avoir un problème si les fichiers ont un Newline dans
leur nom (à cause du print du find).

Mais c'est ce genre de programme que j'aurais fait, mais sans utiliser les
"$(" trop typés. Et pour faire un programme vraiment sûr, j'aurais fait le
script en Perl.

--
Éric Lévénez -- <http://www.levenez.com/>
Unix is not only an OS, it's a way of life.

Avatar
pas.de.spam
Anonyme wrote:

Pierre-Olivier TAUBATY wrote:

Bonjour à tous,

Voilà, j'ai un problème assez complexe à résoudre et je ne pense pas
m'en sortir par la voie clicodromique.

J'ai environ 1200 dossiers contenant chacun 1 fichier (y en avait plus
avant, mais je les ai virés.

J'aimerais renommer, en une seule fois chacun des fichiers présents dans
ces dossiers, en ajoutant au dévbut du nom, les 5 premiers caractères
présent au début du nom du dossier ...

Je ne doute pas que vous allez me sortir un formule du tonnerre de Zeus,
et je vous en remercie d'avance.

Bonne Journée


Bon, j'arrive après la bataille, mais voici ma modeste contribution :

#!/bin/zsh

RepATraiter="chemin/vers/dossier"

find "$RepATraiter" -type f -print | while read ficpath
do
ficname=$(basename "$ficpath")
dirname=$(dirname "$ficpath")
dirprefix=$(basename "$dirname")
dirprefix=${dirprefix:0:5}
echo "${ficname}" |grep "^[0-9]" >/dev/null || {
mv "${ficpath}" "${dirname}/${dirprefix}${ficname}"
}
done


Explciations :
- Par rapport aux autres propositions, je me fiche de savoir où se place
le dossier contenant le fichier, et je prends le nom du dossier
contenant le fichier, pas le nom du sous-dossier du dossier courant.
(c'est utile si tes 1200 dossiers ne sont pas au même niveau)


En fait, tous mes dossiers sont au même niveau d'arborescence, dans un
seul et même dossier.

- J'ai détaillé sur plusieurs lignes pour plus de lisibilité, ça ne le
rend pas moins performant mais beaucoup plus lisible.

- Les espaces et caractères spéciaux dans les noms de dossiers et
fichiers sont correctements traités.

- Je l'ai fait en zsh mais ça devrait marcher en bash...

- si tu le mets dans un script, tu peux remplacer "chemin/vers/dossier"
par "${1}" et tu donnes alors le dossier à traiter en paramètre du
script.


Merci beaucoup, Jayce, ça fonctionne à la perfection.

Purée, ce que j'aimerais savoir faire ...
--
PO.

Pour m'écrire : po_taubaty(arobas)yahoo(point)fr


Avatar
pas.de.spam
Pierre-Olivier TAUBATY wrote:

Patrick Stadelmann wrote:

In article <1ifb1js.qv3fph10wqr3cN%,
(Pierre-Olivier TAUBATY) wrote:

Merci, Patrick, mais ...... euh ......... je fais quoi avec ce script ?
que je suppose Apple Script.


Coller le script dans l'Editeur de Script et cliquer sur "Exécuter".

Merci, c'est simple, mais vu que je n'ai jamais ouvert AppleScript,

j'ignorais quoi faire. Comme une poule devant un bête opinel, quoi ...

Bonne Nuit.


Je te remercie, ça fonctionne très bien. EN fait, j'ai testé toutes
versions que l'on m'a proposé, par égard pour vos efforts.
--
PO.

Pour m'écrire : po_taubaty(arobas)yahoo(point)fr



Avatar
pas.de.spam
Pierre-Olivier TAUBATY wrote:

Martin Costabel wrote:

Pierre-Olivier TAUBATY wrote:
Patrick Stadelmann wrote:

In article <1ifamhe.1lygny2136m2k0N%,
(Pierre-Olivier TAUBATY) wrote:

J'ai oublié de préciser un détail important : si le renommage pouvait
être conditionnel, à savoir, si le nom du fichier comporte des chiffres
en début, ne pas le renommer.




En bash, c'est plus court (une ligne):

for F in */* ; do B=`basename $F`; D=`dirname $F`; echo $B | grep
'^[0-9]' >/dev/null || mv $F $D/`echo ${D:0:3}$B`; done

Ou, en plus joli et plusieurs lignes

for F in */*
do
B=`basename $F`
D=`dirname $F`
echo $B | grep '^[0-9]' >/dev/null || mv $F $D/`echo ${D:0:5}$B`
done


Merc, j'essayerais cela demain matin, lorsque j'aurais les yeux en face
des trous.


Ceci suppose que tes noms de fichiers ne comportent pas de blancs et que
ton dossier de travail soit celui dans lequel se trouvent tes 1200
dossiers. Sinon, taper auparavant

cd /nom/du/dossier/en/question


Aïe Aïe Aïe, des espaces j'en ai des milliers, puisque chaque fichier
porte le titre du DVD auquel il correspond (bibliothèque de scan des
jaquettes.

Cela dit, avec automator, je peux aisément remplacer tout caractère,
très très rapidement dans toute une arborescence. Donc dans un premier
temps, je remplacerais tous les espaces par des _ et ensuite, manoeuvre
inverse.
Je te dirais ce que cela a donné demain, ou Lundi.

Merci encore.


Je te remercie, ça fonctionne. J'ai pris la précaution de remplacer tout
ce qui était espace.
--
PO.

Pour m'écrire : po_taubaty(arobas)yahoo(point)fr





1 2 3 4