76 votes

Raccourci Shell/Bash pour le renommage en masse de fichiers dans un dossier

Existe-t-il un raccourci en Shell/Bash qui peut renommer tous les fichiers dans un dossier en fonction d'une expression régulière ou d'un autre critère. Ce que je cherche ici, c'est dans mon dossier de documents, qui contient disons 100 fichiers texte avec la convention de nommage suivante:

-doc-.txt.

J'ai besoin de renommer tous les fichiers avec la convention donnée ci-dessus en juste:

doc-.txt

Existe-t-il une seule commande qui peut m'aider avec ce qui précède?

138voto

Sorin Points 1662

Je suggérerais quelque chose comme ceci:

for i in *-doc-*.txt; do mv "$i" "${i/*-doc-/doc-}"; done

${i/*-doc-/doc-} remplace la première occurrence de *-doc- par doc-.

Si vous avez besoin de faire plus d'un remplacement (voir commentaire numéro 1), vous devez utiliser la variante ${var//Pattern/Replacement}. Si vous devez remplacer le début du nom, vous devez utiliser ${var/#Pattern/Replacement}, si vous devez remplacer la fin (c.-à-d. l'extension) vous devez utiliser le formulaire ${var/%Pattern/Replacement}.

Voir l'Expansio des Paramètres Shell pour plus de détails. Cette expansion est spécifique à bash.

2 votes

Cela a été utile pour un cas légèrement différent; où je voulais remplacer tous les espaces dans certains noms de fichiers par des tirets: for i in *; do mv "$i" ${i//\ /-}; done. Notez que pour que cela fonctionne, j'ai dû mettre entre guillemets les noms de fichiers d'origine.

0 votes

Je l'ai utilisé pour supprimer .sh de tous les noms de scripts :-) pour i in *.sh; faire mv $i ${i/.sh/}; fin.

1 votes

@erm3nda faites attention : ${i/.sh/} supprime la première correspondance de la chaîne .sh. Pour vous assurer de supprimer l'extension (ce que je suppose que vous voulez), vous devriez utiliser ${i/%.sh/}

25voto

ldueck Points 332

Si vous avez rename, alors rename 's/^.*-doc-/doc-/' *.txt devrait fonctionner.

15voto

elias Points 6255

Il y a prename, qui vous permet d'utiliser REGEX:

prename 's/^.*-doc-(.*\.txt)$/doc-$1/'  *.txt

Utilisez l'option -n pour simuler:

prename -n 's/^.*-doc-(.*\.txt)$/doc-$1/'  *.txt

Note: Ceci est expédié sous le nom de rename dans de nombreuses distributions Linux, mais pas dans toutes - donc j'utilise le nom canonique pour l'utilitaire qui est livré avec Perl.

10voto

Ron Wertlen Points 129

Si vous souhaitez vous enfoncer dans les sous-répertoires, il y a aussi :

find . -maxdepth N -type f -name "$pattern" | sed -e 'p' -E -e "s/$str1/$str2/g" | xargs -n2 mv

Sur les systèmes qui prennent en charge automatiquement les Regexps étendus, vous pouvez omettre le -E.

Avantages :

  • s'enfonce dans les sous-répertoires
  • vous pouvez contrôler la profondeur maximale de la récursivité
  • vous pouvez renommer des fichiers et/ou des répertoires (-type f|d)

Inconvénients :

  • des regexps légèrement plus compliqués, car vous devez extraire le chemin pour accéder au nom du fichier

(réponse modifiée depuis ici)

0 votes

Je reçois l'erreur suivante en exécutant ceci : sed: -e expression #2, char 33: unterminated `s' command. Des conseils ?

8voto

Wes Hardaker Points 10426

La commande rename intégrée à la plupart des systèmes Linux le fera facilement.

Personnellement, je préfère aussi les expressions régulières, c'est pourquoi je traîne ce script depuis très très longtemps (à lire : depuis la fin des années 80 ou le début des années 90) :

#!/usr/bin/perl

($op = shift) || die "Utilisation : $0 expr [fichiers]\n";

if(!@ARGV)
  {
  @ARGV = ;
  chop(@ARGV);
  }

for (@ARGV)
  {
  $était = $_;
  eval $op;
  die $@ if $@;

  if ($was ne $_)
    {
    print "rename($was,$_)\n";
    rename($was,$_);
    }
  }

Ce qui, une fois installé, vous permet de faire des choses comme ceci :

nom-du-script 's/.*-doc(.*).txt/doc$1.txt/' *.txt

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X