Rename en récursif

Bonjour,
Mon problème me paraît simple en apparence mais malgré mes recherches je dois avouer que je sèche…

je souhaite lancer la commande suivante en mode récursif :

rename 's/ /_/g' *

et il n’y a pas d’option -r à rename :mrgreen:

Je suppose que je dois faire un script avec une boucle mais je ne sais pas du tout comment m’y prendre…

Merci !

[quote=“LAV-FRED”]Bonjour,
Mon problème me paraît simple en apparence mais malgré mes recherches je dois avouer que je sèche…

je souhaite lancer la commande suivante en mode récursif :

rename 's/ /_/g' *

et il n’y a pas d’option -r à rename :mrgreen:

Je suppose que je dois faire un script avec une boucle mais je ne sais pas du tout comment m’y prendre…

Merci ![/quote]

C’est peut-être pas exactement ce que tu recherche mais il fut un temps ou j’avais deux disques de 500Go à ranger avec tous un tas de cochonneries dont des logs et des fichiers de configurations et je me suis servi de pyrenamer.

Bonjour,

Voici le script :

[code]#!/bin/sh

Script deblank.sh.

Prend un seul argument (un nom de repertoire).

Remplace tous les blancs par des underscores dans le repertoire passe en

argument.

Fonctionne recursivement.

find “$1” | while read path; do
escape_path=echo "$path" | sed 's/ /_/g'
mv -T “$path” "$escape_path"
done[/code]

Merci à toi branch !
Mais comme une solution toute faite ne présente au final que peu d’intérêt aurais tu l’aimabilité de m’expliquer comment le tout fonctionne par ce que là c’est assez obscur pour moi :017
Merci !

Bien sûr.

$1 est le premier argument passé au script. On le met entre guillemets au cas ou il contiendrait des espaces (il serait alors interprété par find comme plusieurs noms de fichiers distincts).

Le résultat de cette commande vas être une liste de noms de fichiers (un par ligne). Pour te faire une idée de la sortie, tape “find Desktop” par exemple.

Ensuite on va faire une action sur chacun des noms de fichiers renvoyés par find. Cette action est bien sûr de le renommer en remplaçant les espaces par des underscores.

Imaginons que l’on traite une seule ligne renvoyée par find.

On cherche à exécuter la commande :

On utilise l’option -T pour que mv ne traite pas les répertoires de manière spéciale.

Pour obtenir le nouveau nom du fichier, on utilise sed :

Ensuite il faut savoir que les backquotes (``) permettent de créer une commande à partir du résultat d’une autre commande. Par exemple :

ma_variable=`uname -s` echo $ma_variable Linux
Ca permet de stocker le résultat d’une commande dans une variable. Ceci ne fonctionne pas du tout :

ma_variable=uname -s bash: -s : commande introuvable

Enfin la commande interne read permet de lire une ligne de l’entrée standard (stdin). Elle stocke le résultat dans son premier argument.
Essayes

read ma_variable echo $ma_variable

La commande read renvoie VRAI si elle a pu lire quelque chose, FAUX sinon. C’est ce qui permet à la boucle while de terminer.

Je viens de me rendre compte d’un problème avec mon script : si c’est un nom de répertoire qui contient des espaces, ce répertoire va être renommé et ça provoquer des erreurs avec les appels à mv qui suivent. Si les noms de répertoires ne contiennent pas d’espaces ça ne pose pas de problèmes.

Je te corrige ça après mangé.

J’ai corrigé le script. Maintenant il fonctionne quand les répertoires aussi ont des noms avec des espaces.

[code]#!/bin/sh

Script deblank.sh.

Prend un seul argument (un nom de repertoire).

Remplace tous les blancs par des underscores dans les noms des fichiers.

Fonctionne recursivement.

deblank() {
ls -U1 “$1” | while read name; do
path=echo "$1/$name"
escape_name=echo "$name" | sed 's/ /_/g'
escape_path=echo "$1/$escape_name"
if [ “$path” != “$escape_path” ]; then
mv -T “$path” "$escape_path"
fi
if [ -d “$escape_path” -a ! -h “$escape_path” ]; then
deblank "$escape_path"
fi
done
}

deblank “$1”[/code]

Le fonctionnement principal du script à changé. On n’utilise plus find. Maintenant, on remplace les espaces dans les noms de fichier du répertoire actuel, PUIS on va dans les sous-répertoires (qui n’ont plus d’espaces dans leur nom) pour faire la même chose.

On gagne en flexibilité. Par exemple, on peut choisir d’étendre le remplacement des espaces aux fichiers cachés (commençant par un point) en utilisant l’option -a lorsqu’on invoque la commande ls.

Pour comprendre ce qu’il se passe, il faut comprendre les structures conditionnelles du shell et ce qu’est une fonction du shell

Merci à toi !
Je viens de lire un article sur zsh (que je commence à tester immédiatement), et visiblement on peut lancer des recherches récursives, ce qui permettrait peut être d’éviter de faire appel à un script.

De rien ! Au fait j’ai trouvé comment le faire avec find. Du coup le script est plus court et plus robuste.

[code]#!/bin/sh

find “$1” -depth | while read chemin; do
prefixe=echo "$chemin" | sed 's/[^/]*$//'
suffixe=echo "$chemin" | sed -e 's/.*\///' -e 's/ /_/g'
mv -T “$chemin” "$prefixe$suffixe"
done[/code]