Comment nettoyer les extensions de fichiers?

9

J'ai un répertoire avec des fichiers .MP3 dont je voudrais changer les extensions en .mp3. Quelle est la façon la plus simple de procéder? Je pense que quelque chose dans le sens de:

find /RootPath -type f -iname "*.mp3" -exec mv {} sed s/.*MP3/\1.mp3/ \; 

... même si je sais que ce n'est pas tout à fait ça. :) La substitution n'est pas correcte et je ne sais pas comment utiliser à la fois une mvet une sedcommande avec -execin find.

Aurais-je besoin d'un script bash pour cela?

Caleb
la source

Réponses:

12

Voici une façon de le faire dans Bash:

for i in *; do [ "${i/%MP3/mp3}" != "$i" ] && echo "$i" "${i/%MP3/mp3}"; done

J'ai utilisé echoici, donc la commande elle-même ne fait rien d'autre que d'imprimer des paires de noms de fichiers. Si cette liste représente les modifications que vous souhaitez apporter, vous pouvez alors passer echoà quelque chose comme mv -i --qui va alors déplacer vos fichiers (et vous demander avant d'écraser).

Brève explication:

L' foritération passe par chaque fichier correspondant à *. Ensuite, nous déterminons si l'extension est déjà en minuscules, si c'est le cas, nous continuons, si ce n'est pas le cas, nous procédons à son déplacement (ou l'écho, selon le cas). Cela utilise les opérations de chaîne intégrées de Bash que vous pouvez lire ici: http://tldp.org/LDP/abs/html/string-manipulation.html

Steven D
la source
Merci pour votre réponse et en m'indiquant un lien sur la manipulation des chaînes bash!
7

En zsh:

autoload zmv
zmv '(*).MP3' '$1.mp3'   # rename files in the current directory only
zmv '(**/)(*).MP3' '$1$2.mp3'  # rename files in subdirectories as well

Pour prendre également soin de .Mp3ou .mP3fichiers:

zmv '(**/)(*).(#i)mp3' '$1$2.mp3'
Gilles 'SO- arrête d'être méchant'
la source
6

Vous pouvez utiliser la commande rename (attention, il existe deux implémentations principales avec des API différentes) pour celles-ci. Par exemple, pour changer la casse des extensions de nom de fichier du haut vers le bas, essayez ceci:

  • avec renamefrom util-linux(parfois appelé rename.ul), en supposant qu'il .JPGne se produit qu'une seule fois dans les noms de fichier

    rename -- .JPG .jpg *.JPG
  • avec le renamefrom perl(parfois appelé prename; plusieurs variantes ont été publiées):

    rename 's/\.JPG$/.jpg/' ./*.JPG

Voici quelques tutoriels sur la façon dont il est passé d'un script bash désordonné à cette commande simple pour exactement votre cas d'utilisation.

Une autre commande sophistiquée pour ce faire est pax. Si vous utilisez ZSH pour votre shell, vous pouvez également utiliser zmv.

Caleb
la source
super! exactement ce dont j'avais besoin
JoshP
Je reçois une erreur syntax error at (user-supplied code), near "."lorsque j'exécute cette commande.
Ryan Gates
3

Utilisez perl-rename , couteau suisse de renommage de fichiers avec des expressions régulières (sur ubuntu, cela est fourni avec le paquet perl en tant que prename):

# Replace prename as appropriate (i.e. if you've got it installed under a different name
find /RootPath -type f -iname '*.mp3' -print0 | xargs -0 prename 's/mp3$/mp3/i'

Si vous êtes du genre prudent, utilisez les options -n et -v pour renommer perl pour voir ce qu'il fera réellement.

Kjetil Jorgensen
la source
Merci pour votre réponse. Ne pas avoir de perlrename sur le serveur, mais je vais jouer avec lui plus tard dans la journée!
0

Vous avez besoin d'un script, car les "extensions" sous Linux ne sont en fait que des parties de la chaîne de nom de fichier. Vous devez faire quelques manipulations de chaînes dans le script pour obtenir le nouveau nom.

#!/bin/bash
for NAME in *.JPG
do
    PREFIX=${NAME%.*}
    NEWNAME="$PREFIX.jpg"
    mv "$NAME" "$NEWNAME"
done

Les guillemets doubles sont importants si vous avez des noms de fichiers contenant des espaces. Je pensais qu'une partie de la double citation était un peu évidente.

Bruce Ediger
la source
1
Il n'y a rien de mal à dire avec votre script, mais vous n'avez absolument pas besoin d'un script pour cela. Il y a probablement une douzaine de façons de le faire sur une seule ligne dans la plupart des shells, et de nombreux utilitaires pour le rendre facile aussi.
Caleb
0

En bash:

# renaming files in the current directory only
for f in *.MP3; do mv "$f" "${f%.MP3}.mp3"; done  

# renaming files in subdirectories as well
for f in *{,/*}.mp3; do mv "$f" "${f%.MP3}.mp3"; done
Maxime R.
la source
0

sauvegardez d'abord vos fichiers! vous pouvez utiliser un one-liner en python:

python -c "import glob,os; [os.rename(fn, fn.replace('.MP3', '.mp3')) for fn in glob.glob('PATH_TO_YOUR_DIRECTORY')]"

ÉDITER:

Voici une explication détaillée de la façon dont fonctionne le one-liner. En utilisant python -cnous passons une commande à l'interpréteur python. Après avoir importé les bibliothèques ospour la renamefonction et globpour la liste des fichiers, nous devons parcourir la liste des fichiers dans le répertoire donné, que j'ai appelé PATH_TO_YOUR_DIRECTORY, par exemple quelque chose comme ./*pour tout dans le répertoire actuel.

Dans la syntaxe à une ligne, malheureusement, les forboucles ne fonctionnent pas après la importnotation, nous devons donc utiliser la notation entre crochets. C'est-à-dire que pour chaque nom de fichier ou de répertoire qui globnous donne le chemin donné sous la forme d'une chaîne, nous remplaçons * .MP3 par * .mp3.

Étant donné que OP n'a pas mentionné la recherche récursive, je ne l'ai pas inclus en premier lieu.

xaratustra
la source