web-dev-qa-db-fra.com

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

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 travaille pour moi. Je soupçonne que c'est parce que la chaîne que j'essaye de remplacer a un # dedans. Existe-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. Ils 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 pour la remplacer par" sûre ".

50

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 
24
DTK

Remplacer # par somethingelse pour les noms de fichiers dans le répertoire courant (non récursif), vous pouvez utiliser l'utilitaire GNU rename :

rename  's/#/somethingelse/' *

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

Pour votre cas, vous souhaitez utiliser

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

Notez que si vous souhaitez uniquement opérer sur une certaine 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 modifier réellement les noms de fichiers, utilisez le -n drapeau:

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 rename peut être installé en utilisant homebrew : brew install rename.

83
KrisWebDev

recherchez la liste des fichiers, puis remplacez le mot clé. ci-dessous est un exemple

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

Pour échapper à # à partir du shell, utilisez simplement des guillemets simples ('#'), double citation ("#") ou barre oblique inverse (\#).

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

rename '#U00a9' safe *.jpg
20
mik

je ne sais pas comment le faire dans sed, 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 à l'aide de la commande move (mv)
  3. utilise la substitution native des paramètres bash $ {var/Pattern/Replacement} pour créer le nouveau nom ("$ {f/# U00a9/safe}")

En savoir plus sur la substitution de paramètres (qui est très sous-utilisée OMI): http://www.tldp.org/LDP/abs/html/parameter-substitution.html

12
Gregory Patmore

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: il faut échapper '#' avec \ en ligne de commande):

rename \#U00a9 safe *.jpg

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

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

1
Ezra Citron

Voici la solution de DTK enveloppée dans 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
Slava Fomin II

En fait, rename a une option exactement pour celle appelée --subst ou -s en bref. Pas besoin d'utiliser la syntaxe regex.

rename -s '#U00a9' 'safe' *

Si vous souhaitez remplacer/substituer plusieurs occurrences, utilisez --subst-all ou -S.

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

rename -d '#U00a9' *
0
lapin

Suivez ces étapes

ls Lucky-#U00a9NBC*.jpg 

Affiche tous les noms de fichiers jpg avec Lucky-#U00a9NBC*

rename 's/Lucky-#U00a9NBC/Lucky-safeNBC/' *.jpg

Après avoir exécuté cette commande, tous les Lucky-#U00a9NBC remplacer par Lucky-safeNBC.

 ls Lucky-safeNBC*.jpg

Vous pouvez voir que tous les fichiers sont renommés

0
Kalana

Je dirais plus probable #U00a9 est censé représenter le caractère U + 00A9 ici (©).

Si vous vouliez revenir à ©, codé dans le jeu de caractères des paramètres régionaux, vous pouvez le faire avec les variantes Perl de rename (parfois appelées prename):

rename '
  use Encode::Locale;
  use Encode;
  s/#U([0-9a-f]{4})/chr hex $1/gie;
  $_ = encode(locale_fs => $_)' ./*'#'[uU]*
0
Stéphane Chazelas