Linux shell bash remplacer chaîne de caractère
Résolumamiemando Messages postés 33262 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 6 septembre 2024 - 16 août 2024 à 14:17
- Linux shell bash remplacer chaîne de caractère
- Caractère ascii - Guide
- Caractere speciaux - Guide
- Caractère spéciaux - Guide
- Remplacer disque dur par ssd - Guide
- Remplacer word - Guide
11 réponses
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.
Modifié le 16 août 2024 à 13:59
hello
voir man 1 rename
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.
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é
Vous n’avez pas trouvé la réponse que vous recherchez ?
Posez votre questionModifié 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.
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 $
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.
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
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
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 {} \;
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.
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.