Comment renommer plusieurs fichiers en remplaçant la chaîne dans le nom du fichier? cette chaîne contient un "#"


43

https://serverfault.com/questions/70939/how-to-replace-a-text-string-in-multiple-files-in-linux

https://serverfault.com/questions/228733/how-to-rename-multiple-files-by-replacing-word-in-file-name

https://serverfault.com/questions/212153/replace-string-in-files-with-certain-file-extension

https://serverfault.com/questions/33158/searching-a-number-of-files-for-a-string-in-linux

Ces articles mentionnés ont tous répondu à ma question. Cependant, aucun d'entre eux ne fonctionne pour moi. Je suppose que c'est parce que la chaîne que je tente de remplacer contient un #. Y a-t-il un moyen spécial de résoudre ce problème?

J'ai un fichier image qui a été remplacé par # U00a9 lors d'une migration de site. Celles-ci ressemblent à ceci:

Lucky-#U00a9NBC-80x60.jpg
Lucky-#U00a9NBC-125x125.jpg
Lucky-#U00a9NBC-150x150.jpg
Lucky-#U00a9NBC-250x250.jpg
Lucky-#U00a9NBC-282x232.jpg
Lucky-#U00a9NBC-300x150.jpg
Lucky-#U00a9NBC-300x200.jpg
Lucky-#U00a9NBC-300x250.jpg
Lucky-#U00a9NBC-360x240.jpg
Lucky-#U00a9NBC-400x250.jpg
Lucky-#U00a9NBC-430x270.jpg
Lucky-#U00a9NBC-480x240.jpg
Lucky-#U00a9NBC-600x240.jpg
Lucky-#U00a9NBC-600x250.jpg
Lucky-#U00a9NBC.jpg

et je veux le changer en quelque chose comme ceci:

Lucky-safeNBC-80x60.jpg
Lucky-safeNBC-125x125.jpg
Lucky-safeNBC-150x150.jpg
Lucky-safeNBC-250x250.jpg
Lucky-safeNBC-282x232.jpg
Lucky-safeNBC-300x150.jpg
Lucky-safeNBC-300x200.jpg
Lucky-safeNBC-300x250.jpg
Lucky-safeNBC-360x240.jpg
Lucky-safeNBC-400x250.jpg
Lucky-safeNBC-430x270.jpg
Lucky-safeNBC-480x240.jpg
Lucky-safeNBC-600x240.jpg
Lucky-safeNBC-600x250.jpg
Lucky-safeNBC.jpg

MISE À JOUR:

Ces exemples commencent tous par "LU00a9ucky mais voici de nombreuses images avec des noms différents. Je cible simplement la partie" # U00a9 "de la chaîne à remplacer par" safe ".


3
Alors qu'as-tu réellement essayé? Je vois que vous avez lié à quelques questions et dites qu'elles ont échoué, mais comment ont-elles échoué? OMI le meilleur exemple utilise la renamecommande. Je soupçonne que votre changement de nom serait aussi simple que rename -n 's/#/safeNBC/' *.jpg.
Zoredache

J'ai essayé rename -n 's/#U00a9/safe/' *.jpget la commande a été acceptée mais aucun changement ne s'est produit.

Bien sûr, comme vous l'avez vu dans la documentation que vous avez sûrement examinée, -nc'est l' no actoption. Ce qui vous permet de voir si cela fonctionne avant de l'utiliser. Le résultat affiché à l'écran indique-t-il correctement les nouveaux noms potentiels?
Zoredache

Je m'excuse d'avoir copié et collé votre exemple sans y accorder toute votre attention. J'ai exécuté la commande de changement de nom sans le -n. Je crois que @DTK a résolu le problème, je n’échappais pas au #.

Remplacement des chaînes dans les noms de fichiers sous MacOS: superuser.com/questions/152627/…
Anton Tarasenko

Réponses:


65

Pour remplacer #par les somethingelsenoms de fichiers dans le répertoire actuel (non récursif), vous pouvez utiliser l' utilitaire de renommage GNU :

rename  's/#/somethingelse/' *

Des personnages comme -doit être échappé avec un \.

Pour votre cas, vous voudriez utiliser

rename 's/#U00a9/safe/g' *

Notez que si vous ne souhaitez utiliser qu'une sélection de fichiers, par exemple uniquement *.jpg, ajustez l'entrée finale pour qu'elle corresponde à cette sélection:

rename 's/#U00a9/safe/g' *.jpg

Pour effectuer un test avant de changer les noms de fichiers, utilisez l' -nindicateur:

demo/> ls                               
Lucky-#U00a9NBC-125x125.jpg  
Lucky-#U00a9NBC-150x150.jpg 

demo/> rename -n 's/#U00a9/safe/g' *.jpg
rename(Lucky-#U00a9NBC-125x125.jpg, Lucky-safeNBC-125x125.jpg)
rename(Lucky-#U00a9NBC-150x150.jpg, Lucky-safeNBC-150x150.jpg)

Pour OS X, GNU renommage peut être installé à l' aide homebrew : brew install rename.


Cela n'a pas fonctionné sur ma machine (Arch Linux), mais la réponse de mik l'a fait.
Marcvangend

@marcvangend Quelle version de renameutilisez-vous? # sudo pacman -S perl-renameinstallera la version perl, qui est plus puissante et qui suffira peut-être pour que cette réponse fonctionne pour vous.
John Gowers

@ JohnGowers Merci! Je n'avais pas réalisé qu'il y avait deux versions. Sur mon système, rename --versionretourne rename from util-linux 2.29.2donc ce n'est effectivement pas la version Perl.
Marcvangend

5
Il existe deux renameutilitaires communs, mais aucun d'entre eux n'est développé par GNU: les distributions basées sur Debian incluent un renameutilitaire avec leur paquet Perl, tandis que les distributions basées sur Red Hat utilisent l' renameutilitaire de l' util-linuxorganisation du noyau Linux. Votre lien est avec la fonctionrename C de la bibliothèque standard GNU.
Anthony G - justice pour Monica le

2
Dans cette réponse, pourquoi nous devons écrire /genrename 's/#U00a9/safe/g' *
Nikhil

24

trouver la liste des fichiers puis remplacer le mot clé. ci-dessous est un exemple

find . -name '*jpg' -exec bash -c ' mv $0 ${0/\#U00a9NBC/safeNBC}' {} \;

1
Vous avez besoin de guillemets autour de vos mvarguments, au cas où il y aurait des espaces dans le nom
Stop Harming Monica

Je devais remplacer tous les fichiers * _spec.rb par * _controller_spec.rb et votre solution a fonctionné pour moi. Merci
Jedi

Merci. Cela résoudra mon problème
Fabio Souza

19

Ce n'est pas difficile, assurez-vous simplement d'échapper l'octothorpe (#) dans le nom en ajoutant une barre oblique inversée (\).

find . -type f -name 'Lucky-*' | while read FILE ; do
    newfile="$(echo ${FILE} |sed -e 's/\\#U00a9/safe/')" ;
    mv "${FILE}" "${newfile}" ;
done 

Votre explication est logique, en évitant les #sons comme ce dont j'avais besoin. Je ne vois pas de barre oblique inverse dans votre exemple. Devrait-il ressembler à ceci: s/\#U00a9/safe/

@LeFrancisShelhamer bonne prise. Il a avalé la barre oblique inverse. Je vais modifier.

17

Pour sortir #du shell, utilisez simplement des guillemets simples ( '#'), des guillemets doubles ( "#") ou des barres obliques inverses ( \#).

Le plus simple dans votre cas serait d'utiliser la renamecommande (si elle est disponible):

rename '#U00a9' safe *.jpg

2
Merci. Alors que la réponse la plus votée ( rename 's/#/somethingelse/' *) ne fonctionnait pas sur ma machine (Arch Linux), celle-ci fonctionnait.
Marcvangend

1
Cela fonctionne en utilisant la commande rename de util-linux.
imclean

10

je ne sais pas comment faire, mais vous pouvez essayer ceci dans un shell bash:

for f in Lucky-#U00a9NBC-*.jpg; do mv -v "$f" "${f/#U00a9/safe}"; done;

explication:

  1. parcourt tous les noms de fichiers correspondant au glob (Lucky- # U00a9NBC - *. jpg)
  2. renomme le fichier en utilisant la commande move (mv)
  3. utilise la substitution de paramètre bash native $ {var / Pattern / Replacement} pour créer le nouveau nom ("$ {f / # U00a9 / safe}")

Pour en savoir plus sur la substitution de paramètres (qui est une OMI extrêmement sous-utilisée): http://www.tldp.org/LDP/abs/html/parameter-substitution.html


Bien que ce code puisse répondre à la question, il n'est pas très utile en soi. Expliquer comment résoudre le problème améliorerait l’utilité et la valeur à long terme de la réponse.
Anthony G - justice pour Monica

ajout d'une explication pas à pas et de lectures complémentaires conformément au commentaire d'Anthony.
Gregory Patmore

1

Les exemples ci-dessus ne fonctionnaient pas sur mon système (CentOS 5.6). J'ai donc trouvé une commande (peut-être plus spécifique au système) qui fonctionne (remarque: nécessité d'échapper à '#' avec la \ligne de commande):

rename \#U00a9 safe *.jpg

[Aussi: je n'ai pas encore assez de réputation pour commenter, alors en réponse à la question de Nikhil concernant l'utilisation de /gin rename 's/old_string/new_string/g'(posée dans les commentaires pour une autre réponse ci-dessus):

Utilisez le gmodificateur pour effectuer une substitution "globale" (c'est-à-dire pour substituer new_string à old_string autant de fois que old_string se produit). Cela ne devrait pas être nécessaire dans ma réponse car le renamesera appliqué à tous les fichiers spécifiés avec *. Voir https://www.computerhope.com/unix/rename.htm pour une explication concise de ce modificateur et d'autres.]


Correct; Les systèmes d'exploitation dérivés de Fedora tels que CentOS ont une version différente de renamecelle des systèmes d'exploitation dérivés de Debian. Voir unix.stackexchange.com/a/238862/135943 . Et au fait, CentOS 5.6 est assez ancien et je vous recommande de le mettre à jour.
Wildcard

Ah, merci pour l'explication + lien. Le système d'exploitation obsolète est au travail et il ne m'appartient donc pas de mettre à niveau :) mais un nouveau cluster est en construction et nous allons probablement le mettre à niveau lorsque nous passerons ...
Ezra Citron

0

Voici la solution de DTK intégrée à une fonction bash réutilisable:

function renameFilesRecursively () {

  SEARCH_PATH="$1"
  SEARCH="$2"
  REPLACE="$3"

  find ${SEARCH_PATH} -type f -name "*${SEARCH}*" | while read FILENAME ; do
      NEW_FILENAME="$(echo ${FILENAME} | sed -e "s/${SEARCH}/${REPLACE}/g")";
      mv "${FILENAME}" "${NEW_FILENAME}";
  done

}

Voici comment vous pouvez l'utiliser:

renameFilesRecursively /home/user/my-files apple orange

0

A en fait renameune option exactement pour cela appelé --substou -sen bref. Pas besoin d'utiliser la syntaxe regex.

rename -s '#U00a9' 'safe' *

Si vous souhaitez remplacer / remplacer plusieurs occurrences, utilisez --subst-allou -S.

BTW, je voulais seulement remplacer une chaîne par rien (retirez-la du nom du fichier) ... eh bien nous avons aussi une option pour elle -d/--deleteet -D/--delete-all:

rename -d '#U00a9' *

-1

Une autre option consiste à utiliser pyRenamerune application spécialement conçue pour renommer des lots.

Il peut être installé avec sudo apt-get install pyrenamer

Pour plus de détails sur l'utilisation, reportez-vous à son fichier README sur GitHub .


1
Si vous pensez vraiment que cela pourrait répondre à la question, veuillez ajouter une explication à votre réponse. De lui-même, il installe seulement un paquet. Vous devez expliquer le rôle de la commande et fournir un exemple permettant de gérer les exigences spécifiques de l'OP.
Roaima
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.