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 ".
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
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
.
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}' {} \;
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
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:
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
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.]
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
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' *
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
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]*