Linux shell bash remplacer chaîne de caractère

Résolu
zatox19 Messages postés 31 Date d'inscription samedi 24 septembre 2022 Statut Membre Dernière intervention 14 août 2024 - Modifié le 16 août 2024 à 13:55
mamiemando Messages postés 33426 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 13 décembre 2024 - 16 août 2024 à 14:17

Bonjour

Comment remplacer une chaîne de caractères par une autre dans les noms des dossiers sous-dossiers et fichiers d'un répertoire ? Je dis bien dans les NOMS que portent les dossiers sous-dossiers et fichiers.

Merci pour vos réponses.

A voir également:

11 réponses

zatox19 Messages postés 31 Date d'inscription samedi 24 septembre 2022 Statut Membre Dernière intervention 14 août 2024 1
Modifié le 16 août 2024 à 14:05

Bonsoir,

La commande qui marche chez moi c'est celle-ci:

find . -type f,d -exec rename -va  $chaine1 $chaine2 {} \;

Auparavant, j'ai trouvé pour connaître le nombre maximum de niveaux dans l'arborescence concernée avec cette commande :

find 2>/dev/null | awk -F '/' '{print NF-1}' | sort -n | tail -n 1 > nb_niveaux.txt

Dans ce cas le nombre de niveaux max se trouve dans nb_niveaux.txt ensuite il suffit de faire une boucle de 1 à nb_niveaux.txt et de passer dans la boucle la commande :

find . -type f,d -exec rename -va  $chaine1 $chaine2 {} \;

Merci pour votre aide, il y a peut-être mieux à faire mais cette solution me convient très bien.

1
mamiemando Messages postés 33426 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 13 décembre 2024 7 809
16 août 2024 à 14:17

Bonjour,

Si ça peut te consoler, à mon avis, tu ne peux pas faire beaucoup mieux. En effet, rename ne modifie que 1 fichier au sens large (i.e., un dossier ou un fichier régulier). Donc si tu as N dossiers imbriqués et qu'il faut renommer chacun d'entre eux, alors N fichiers qui sont mis en jeu, et donc que tu dois faire N appels à rename.

0
dubcek Messages postés 18755 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 14 novembre 2024 5 622
Modifié le 16 août 2024 à 13:59

hello

voir man 1 rename

0
zatox19 Messages postés 31 Date d'inscription samedi 24 septembre 2022 Statut Membre Dernière intervention 14 août 2024 1
Modifié le 16 août 2024 à 13:58

Bonjour,

Merci pour ta réponse. Effectivement, ça marche très bien, en se mettant dans le répertoire à l'intérieur duquel on veut renommer les dossiers et fichiers en remplaçant "chaîne1" des noms de fichiers et dossiers par "chaîne2".

Exemple : je me mets dans le dossier /home/user/test-remplacer-choeur-par-chœur/ dans ce dossier j'ai ceci:

[robert@rmageia9p1 test-remplacer-choeur-par-chœur]$ ls -l
total 32
drwxr-xr-x 2 robert robert 4096 août  10 10:42 choeur-choeurs-de-loups/
-rw-r--r-- 1 robert robert    2 août  10 10:49 Choeur-de-de-loups.ods
drwxr-xr-x 2 robert robert 4096 août  10 10:42 choeur-de-loups/
-rw-r--r-- 1 robert robert    2 août  10 10:49 Choeur-de-loups.ods
-rw-r--r-- 1 robert robert    2 août  10 10:49 choeur-de-loups.odt
-rw-r--r-- 1 robert robert    2 août  10 10:49 choeur-de-loups.pdf
-rw-r--r-- 1 robert robert    2 août  10 10:49 choeur-de-loups.txt
drwxr-xr-x 2 robert robert 4096 août  10 10:42 haut-les-choeurs/

Dans ce dossier je lance la commande :

rename -vna choeur chœur *

Voici ce que ça donne:

[robert@rmageia9p1 test-remplacer-choeur-par-chœur]$ rename -vna choeur chœur *
`choeur-choeurs-de-loups' -> `chœur-chœurs-de-loups'
`choeur-de-loups' -> `chœur-de-loups'
`choeur-de-loups.odt' -> `chœur-de-loups.odt'
`choeur-de-loups.pdf' -> `chœur-de-loups.pdf'
`choeur-de-loups.txt' -> `chœur-de-loups.txt'
`haut-les-choeurs' -> `haut-les-chœurs'

Si j'enlève l'option n à cette commande, elle me renomme bien mes fichiers et dossiers.

Premier problème : je n'ai pas trouvé d'option pour dire de ne pas tenir compte des majuscules. Par exemple, pour "Choeurs", je suis obligé de lancer également la commande :

rename -va Choeur chœur *

Deuxième problème : j'aurais voulu traiter tous les répertoires afin de corriger l'intérieur de chaque répertoire. Style: boucle while ... par exemple ou autre. Il faudrait sans doute que j'écrive un script qui descendrait dans tous les dossiers et passerait la commande rename.

En tous cas merci beaucoup pour ton aide.

0
dubcek Messages postés 18755 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 14 novembre 2024 5 622
10 août 2024 à 12:58

pour ignorer la casse : /i

rename -n 's/choeur/chœur/i'  

pour parcourir l'arborescence

shopt -s globstar
rename -n 's/choeur/chœur/i' **/*

PS : je n.'ai pas tout testé

0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
zatox19 Messages postés 31 Date d'inscription samedi 24 septembre 2022 Statut Membre Dernière intervention 14 août 2024 1
Modifié le 16 août 2024 à 14:01

Bonjour,

Merci pour cette réponse. Je ne connais pas shopt -s globstar.

J'ai essayé de voir ce que ça fait mais je  n'ai pas compris. Il y a pas mal de temps que je n'avais pas trempé dans le shell bash...

Par contre, ceci :

rename -va $chaine_a_remplacer $chaine_de_remplacement *
rename -va $chaine_a_remplacer $chaine_de_remplacement */*

... fonctionne, il faut que j'écrive un script qui récupère tous les sous-dossiers du répertoire concerné puis faire une boucle while dans chacun des répertoires et passer la commande rename. Certains penseront peut-être que ce n'est pas très élégant mais pour le moment je ne vois pas autre chose.

Merci beaucoup pour votre aide.

0
dubcek Messages postés 18755 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 14 novembre 2024 5 622
11 août 2024 à 15:21

on peut traiter chaque fichier d'une arborescence sans boucle

remplacer  file par rename

$ mkdir a b 
$ touch a/a{1..3}
$ touch b/b{1..3}
$ 
$ find *
a
a/a3
a/a1
a/a2
b
b/b3
b/b1
b/b2
$ 
$ shopt -s globstar
$ file **/*
a:    directory
a/a1: empty
a/a2: empty
a/a3: empty
b:    directory
b/b1: empty
b/b2: empty
b/b3: empty
$ 
0
zatox19 Messages postés 31 Date d'inscription samedi 24 septembre 2022 Statut Membre Dernière intervention 14 août 2024 1
Modifié le 16 août 2024 à 14:03

Bonjour,

Merci pour ta réponse. J'ai écris ceci dans un script:

#!/bin/bash

repertoire="/home/robert/Bureau/test-remplacer-choeur-par-chœur/"
cd $repertoire

chaine1="choeur"
chaine2="chœur"

find *
shopt -s globstar
rename -va $chaine1 $chaine2 **/*

Je veux donc changer la chaîne1 choeur par chœur, ça marche sur le premier niveau aussi bien concernant les noms de dossiers que les noms de fichiers. Mais si j'ai d'autres niveaux ça ne marche pas. J'ai pris un exemple où j'ai 7 niveaux, pour que ça marche il faut que j'appelle une fonction de ce style :

remplacer_chaine () {

rename -va $chaine1 $chaine2 *
rename -va $chaine1 $chaine2 */*
rename -va $chaine1 $chaine2 */*/*
rename -va $chaine1 $chaine2 */*/*/*
rename -va $chaine1 $chaine2 */*/*/*/*
rename -va $chaine1 $chaine2 */*/*/*/*/*
rename -va $chaine1 $chaine2 */*/*/*/*/*/*

}

Donc il faut que je fasse autant de rename que j'ai de niveaux, ce n'est pas top. De plus il faut d'abord que j'aille voir le nombre de niveaux pour répéter le rename. Bon j'ai trouvé cette solution mais ça ne me convient pas.

Merci pour votre aide.

0
dubcek Messages postés 18755 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 14 novembre 2024 5 622
Modifié le 12 août 2024 à 11:46

effectivement, shopt -s globstar est moins clair que je croyais

essayer avec find

find . -type f -exec rename -nva "s/$chaine1/$chaine2/" {} \;

ps : je n'ai pas  la même commande rename que toi

0
zatox19 Messages postés 31 Date d'inscription samedi 24 septembre 2022 Statut Membre Dernière intervention 14 août 2024 1
Modifié le 16 août 2024 à 14:04

Bonjour,

Merci pour cette réponse. J'avais essayé cette commande mais de mémoire c'est pareil, il me semble qu'il ne modifie que dans le répertoire courant ...

Je viens de la passer mais j'ai une erreur :

[robert@rmageia9p1 test-remplacer-choeur-par-chœur]$ find . -type f -exec rename -nva "s/choeur/chœur/" {} \;
rename: pas assez d'arguments


Merci

0
dubcek Messages postés 18755 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 14 novembre 2024 5 622
12 août 2024 à 12:54

ps : je n'ai pas  la même commande rename que toi

essaye avec tes options

find . -type f -exec rename -nva  $chaine1 $chaine2 {} \;
0
zatox19 Messages postés 31 Date d'inscription samedi 24 septembre 2022 Statut Membre Dernière intervention 14 août 2024 1
Modifié le 16 août 2024 à 14:03

Bonjour, la commande qui marche:

find . -type f,d -exec rename -va  "chœur" "choeur" {} \;

Le seul problème c'est qu'il faut la lancer autant de fois qu'il y a de niveaux. Il faudrait que je puisse récupérer le nombre de niveaux maximum existant dans l'arborescence et boucler cette commande sur autant de niveaux

Merci pour votre aide.

0