Renommage de masse, * version nix


11

Je cherchais un moyen de renommer un grand nombre de fichiers portant le même nom, un peu comme celui-ci (une question liée à Windows), sauf que j'utilise * nix (Ubuntu et FreeBSD, séparément). Pour résumer, en utilisant le shell (Bash, CSH, etc.), comment renommer en masse un certain nombre de fichiers tels que, par exemple, les fichiers suivants:

Beethoven - Fourrure Elise.mp3
Beethoven - Sonate au clair de lune.mp3
Beethoven - Ode à la joie.mp3
Beethoven - Rage Over the Lost Penny.mp3

sera renommé comme ça?

Fur Elise.mp3
Moonlight Sonata.mp3
Ode to Joy.mp3
Rage Over the Lost Penny.mp3

La raison pour laquelle je veux le faire est que cette collection de fichiers ira dans un répertoire nommé "Beethoven" (c'est-à-dire le préfixe des noms de fichiers), et avoir ces informations sur le nom de fichier lui-même sera redondant.

Réponses:


12

L'utilitaire renommer fera ce que vous voulez.

Utilisez simplement rename 's/Beethoven\ -\ //g' *.mp3


Pouvez-vous modifier pour fournir un lien vers l'utilitaire, ou est-ce standard dans les deux distributions mentionnées (Ubuntu et FreeBSD)?
Chris W. Rea

1
Il est livré avec Perl. Debian l'utilise comme commande renommer, donc je soupçonne qu'Ubuntu aussi. Il existe une autre commande «renommer» qui ne vaut rien, alors consultez la page de manuel.
derobert

wow, la syntaxe de renommage ressemble beaucoup à vim remplacer: D
Dzung Nguyen

le port dans / usr / ports / sysutils / rename fonctionnait parfaitement dans FreeBSD
Josh W.

10

Comme tant de choses avec Linux / Unix, il y a plus d'une façon de le faire!

Certains pourraient utiliser mmv (masse mv).

La commande rename ou prename fournie avec certains packages Perl (Ubuntu et Debian plus récents) peut également le faire.

prename 's/Beethoven\ -\ //g' Beethoven*.mp3

Notez que l'outil de changement de nom sur Fedora 10 n'est pas le même programme que celui-ci et fonctionne différemment. Il fait partie d'un package différent, util-linux-ng et peut être trouvé ici .

Je vais souvent dans le shell pour une boucle par habitude (après que tous ces outils n'existent pas toujours).

mkdir -p Beethoven
for x in Beethoven\ -\ *
do
mv "$x" Beethoven/"${x/Beethoven - /}"
done

Cela va créer le répertoire Beethoven, puis déplacer le fichier vers ce répertoire / nom de fichier, où le nom de fichier a le "Beethoven -" remplacé par rien.

Comme test, avant:

$ ls
Beethoven - Fur Elise.mp3                 Beethoven - Ode to Joy.mp3
Beethoven - Moonlight Sonata.mp3          Beethoven - Rage Over the Lost Penny.mp3

Après:

$ ls Beethoven/
Fur Elise.mp3                 Ode to Joy.mp3
Moonlight Sonata.mp3          Rage Over the Lost Penny.mp3

4

Essayez cette solution, implémentée à l'aide d'une combinaison de grep et rename. Cela suppose que vous avez tout un tas de répertoires que vous devez renommer. S'il n'y en a que quelques-uns, j'opterais pour l'approche manuelle, avec le modèle "Artiste -" codé en dur pour chacun.

# Rename any mp3 files in the directory hierarchy of type "a - b.mp3" to "b.mp3"
find . -name "*.mp3" -exec rename -n -v 's|^(.*/).*-\s*(.*)\s*$|$1$2|g' {} \;

Explication de find :
la commande find recherche tous les fichiers avec l' extension .mp3 dans la hiérarchie de fichiers actuelle et appelle l'argument passé à -exec pour chacun. Notez que dans -exec , {} fait référence à l'argument passé par find (chemin de fichier + nom). Le \;assure que le ;passe est renommé et au lieu d'indiquer la fin de la commande find .

La commande donnée ci-dessus a le commutateur -n (aucune action); par conséquent, il ne vous dira que ce qui se passerait si vous l'exécutiez. Je vous recommande d'exécuter cette commande sans le commutateur -n uniquement après l'avoir exécutée une fois et satisfait des résultats proposés.

Maintenant pour l'expression rationnelle.

  • ^ correspond au début de la chaîne.
  • $ correspond à la fin de la chaîne.
  • . correspond à n'importe quel caractère.
  • *signifie zéro ou plus de la construction précédente. par exemple .*signifie zéro ou plusieurs caractères.
  • \s représente tout caractère spatial.
  • \S représente tout caractère non spatial.
  • Tout ce que l' intérieur ()est capturé et se reflète aussi $1, $2en fonction de sa position.

L'expression régulière:

  • Recherche une structure de répertoire facultative au début, la capture dans $ 1: (.*/)
  • Saute tout jusqu'au " -":.*-
  • Capture le reste de la chaîne, à l'exception des espaces de début et de fin, en $ 2: (.*)
  • Réécrit le fichier en $ 1 $ 2, qui devrait être "/path/to/file/""filename.mp3"

Voici mon test:

/tmp/test$ ls -R
.:
a  b  c  z-unknown.mp3

./a:
a3.mp3                 a - longer title3.mp3  c.mp3   disc2
a - longer title2.mp3  a - long title.mp3     disc 1  the band - the title.mp3

./a/disc 1:
a - title1.mp3  a - title2.mp3

./a/disc2:
a - title1.mp3  a - title2.mp3

./b:
cd - ab - title3.mp3  cd - title1.mp3  cd - title2.mp3  c.mp3

./c:
c-pony2.mp4  c - pony3.mp3  c - pony4.mp3  c-pony.mp3

/tmp/test$ find . -name "*.mp3" -exec rename -v 's|^(.*/).*-\s*(.*)\s*$|$1$2|g' {} \;
./c/c-pony.mp3 renamed as ./c/pony.mp3
./c/c - pony4.mp3 renamed as ./c/pony4.mp3
./c/c - pony3.mp3 renamed as ./c/pony3.mp3
./z-unknown.mp3 renamed as ./unknown.mp3
./a/the band - the title.mp3 renamed as ./a/the title.mp3
./a/a - longer title2.mp3 renamed as ./a/longer title2.mp3
./a/a - longer title3.mp3 renamed as ./a/longer title3.mp3
./a/disc 1/a - title1.mp3 renamed as ./a/disc 1/title1.mp3
./a/disc 1/a - title2.mp3 renamed as ./a/disc 1/title2.mp3
./a/a - long title.mp3 renamed as ./a/long title.mp3
./a/disc2/a - title1.mp3 renamed as ./a/disc2/title1.mp3
./a/disc2/a - title2.mp3 renamed as ./a/disc2/title2.mp3
./b/cd - title1.mp3 renamed as ./b/title1.mp3
./b/cd - title2.mp3 renamed as ./b/title2.mp3
./b/cd - ab - title3.mp3 renamed as ./b/title3.mp3

/tmp/test$ ls -R
.:
a  b  c  unknown.mp3

./a:
a3.mp3  c.mp3  disc 1  disc2  longer title2.mp3  longer title3.mp3  long title.mp3  the title.mp3

./a/disc 1:
title1.mp3  title2.mp3

./a/disc2:
title1.mp3  title2.mp3

./b:
c.mp3  title1.mp3  title2.mp3  title3.mp3

./c:
c-pony2.mp4  pony3.mp3  pony4.mp3  pony.mp3

Les regexp sont des affaires délicates, et j'ai fait beaucoup d'erreurs en les écrivant, donc je serais ravi de toute contribution sur le manque de mérite de celui-ci. Je sais que j'ai trouvé pas mal de tests.


1

J'ai mis au point un programme Java en ligne de commande qui facilite le changement de nom des fichiers (et répertoires), en particulier pour les scripts. C'est gratuit et open source, vous pouvez donc le modifier selon le contenu de votre cœur:

RenameWand
http://renamewand.sourceforge.net/

Quelques exemples d'utilisation pertinents:

Déplacez les fichiers du formulaire "<a> - <b>"vers leur répertoire respectif "<a>":

java -jar RenameWand.jar  "<a> - <b>"  "<a>/<b>"

Triez les fichiers par heure de dernière modification et renommez-les avec un nombre à 3 chiffres:

java -jar RenameWand.jar  "<a>"  "<3|#FT> <a>"

Réorganisez les parties du nom de fichier et changez la casse:

java -jar RenameWand.jar  "<album> - <artist> - <song>.<ext>" 
                          "<artist.upper> <album.title> - <song>.<ext.lower>"

1

zmv L'outil de renommage zsh est très bon.

# zmv "programmable rename"
# Replace spaces in filenames with a underline
zmv '* *' '$f:gs/ /_'
# Change the suffix from *.sh to *.pl
zmv -W '*.sh' '*.pl'
# lowercase/uppercase all files/directories
$ zmv '(*)' '${(L)1}' # lowercase
$ zmv '(*)' '${(U)1}' # uppercase

Plus de notes ici ...


0

Pour les têtes de pingouin, cela se fait facilement dans un script shell ou un script AWK. Pour nous, simples mortels, vous voudrez peut-être essayer Midnight Commander. C'est sur la plupart des distributions Linux, à partir d'une invite de shell de type mc -a. Vous pouvez renommer des fichiers à l'aide d'expressions régulières. J'ai utilisé l'article sur GeekStuff http://www.thegeekstuff.com/2009/06/how-to-rename-files-in-group/ pour m'aider.


0

Voici un exemple simple en ligne de commande. J'avais le mot «blanc» au milieu des noms d'un tas de fichiers png. Je voulais le retirer et ne laisser qu'un seul trait de soulignement. Cela a fait l'affaire:

for i in *.png; do mv "$i" "${i/white/}"; done

0

Utilisez vidir , puis utilisez les fonctionnalités de votre éditeur pour appliquer le modèle de changement de nom.

NOM

vidir - modifier le répertoire

SYNOPSIS

vidir [--verbose] [répertoire | fichier | -] ...

LA DESCRIPTION

vidir permet d'éditer le contenu d'un répertoire dans un éditeur de texte. Si aucun répertoire n'est spécifié, le répertoire actuel est modifié.

Lors de la modification d'un répertoire, chaque élément du répertoire apparaîtra sur sa propre ligne numérotée. Ces chiffres indiquent comment vidir garde la trace des éléments modifiés. Supprimez des lignes pour supprimer des fichiers du répertoire ou modifiez des noms de fichiers pour renommer des fichiers. Vous pouvez également changer de paire de nombres pour échanger les noms de fichiers.

Notez que si "-" est spécifié comme répertoire à éditer, il lit une liste de noms de fichiers depuis stdin et les affiche pour l'édition. Alternativement, une liste de fichiers peut être spécifiée sur la ligne de commande.

EXEMPLES

vidir vidir * .jpeg Utilisations typiques.

trouver | vidir - Modifie également le contenu du sous-répertoire. Pour supprimer des sous-répertoires, supprimez tout leur contenu et le sous-répertoire lui-même dans l'éditeur.

trouver -type f | vidir - Modifiez tous les fichiers du répertoire et des sous-répertoires actuels.

AUTEUR

Joey Hess 2006-2010

Modifications par Magnus Woldrich 2011

DROITS D'AUTEUR

Copyright 2006-2011 le vidir "AUTEUR" comme indiqué ci-dessus.

Sous licence GNU GPL.


0

Sur un * nix sans perl renamedisponible

Sur certains * nix, il n'y a pas de renommage disponible, il est donc nécessaire de le renommer en utilisant une autre méthode. Il y a quelques années, j'ai suggéré zmvici qui, bien que génial, n'est pas nécessairement disponible non plus.

En utilisant les fonctions intégrées et sed, nous pouvons rapidement créer un script shell pour ce faire, ce qui nous donne une syntaxe très similaire au script de changement de nom perl, tout en manquant de gentillesse de gestion des erreurs, il fait le travail.

sedrename() {
  if [ $# -gt 1 ]; then
    sed_pattern=$1
    shift
    for file in $(ls $@); do
      mv -v "$file" "$(sed $sed_pattern <<< $file)"
    done
  else
    echo "usage: $0 sed_pattern files..."
  fi
}

Usage

sedrename 's/Beethoven\ -\ //g' *.mp3

before:

./Beethoven - Fur Elise.mp3
./Beethoven - Moonlight Sonata.mp3
./Beethoven - Ode to Joy.mp3
./Beethoven - Rage Over the Lost Penny.mp3

after:

./Fur Elise.mp3
./Moonlight Sonata.mp3
./Ode to Joy.mp3
./Rage Over the Lost Penny.mp3

Supposons que nous voulions également créer des dossiers cibles ...

Étant donné mvque ne crée pas de dossiers que nous ne pouvons pas utiliser sedrenametels qu'ils sont ici, mais c'est un assez petit changement, donc je pense que ce serait bien de l'inclure aussi.

Nous avons besoin d'une fonction utilitaire abspath(ou d'un chemin absolu) pour pouvoir générer le ou les dossiers cibles pour un modèle sed / rename qui inclut une nouvelle structure de dossiers.

abspath () { case "$1" in
               /*)printf "%s\n" "$1";;
               *)printf "%s\n" "$PWD/$1";;
             esac; }

Cela garantira que nous connaissons les noms de nos dossiers cibles. Lorsque nous renommerons, nous devrons l'utiliser sur le nom du fichier cible.

# generate the rename target
target="$(sed $sed_pattern <<< $file)"

# Use absolute path of the rename target to make target folder structure
mkdir -p "$(dirname $(abspath $target))"

# finally move the file to the target name/folders
mv -v "$file" "$target"

Voici le script complet du dossier ...

sedrename() {
  if [ $# -gt 1 ]; then
    sed_pattern=$1
    shift
    for file in $(ls $@); do
      target="$(sed $sed_pattern <<< $file)"
      mkdir -p "$(dirname $(abspath $target))"
      mv -v "$file" "$target"
    done
  else
    echo "usage: $0 sed_pattern files..."
  fi
}

Bien sûr, cela fonctionne toujours lorsque nous n'avons pas de dossiers cibles spécifiques.

Si nous voulions mettre toutes les chansons dans un dossier, ./Beethoven/nous pouvons le faire:

Usage

sedrename 's|Beethoven - |Beethoven/|g' *.mp3

before:

./Beethoven - Fur Elise.mp3
./Beethoven - Moonlight Sonata.mp3
./Beethoven - Ode to Joy.mp3
./Beethoven - Rage Over the Lost Penny.mp3

after:

./Beethoven/Fur Elise.mp3
./Beethoven/Moonlight Sonata.mp3
./Beethoven/Ode to Joy.mp3
./Beethoven/Rage Over the Lost Penny.mp3

Tour bonus ...

Utilisation de ce script pour déplacer des fichiers de dossiers dans un seul dossier:

En supposant que nous voulions rassembler tous les fichiers correspondants et les placer dans le dossier actuel, nous pouvons le faire:

sedrename 's|.*/||' **/*.mp3

before:

./Beethoven/Fur Elise.mp3
./Beethoven/Moonlight Sonata.mp3
./Beethoven/Ode to Joy.mp3
./Beethoven/Rage Over the Lost Penny.mp3

after:

./Beethoven/ # (now empty)
./Fur Elise.mp3
./Moonlight Sonata.mp3
./Ode to Joy.mp3
./Rage Over the Lost Penny.mp3

Remarque sur les modèles d'expression régulière sed

Les règles de modèle sed standard s'appliquent dans ce script, ces modèles ne sont pas PCRE (Perl Compatible Regular Expressions). Vous auriez pu avoir une syntaxe d'expression régulière étendue sed, en utilisant soit sed -rou sed -E selon votre plateforme.

Voir le conforme POSIX man re_formatpour une description complète des modèles regexp de base et étendus sed.

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.