web-dev-qa-db-fra.com

Raccourci Shell / Bash pour renommer en vrac des fichiers dans un dossier

Existe-t-il un raccourci dans Shell/Bash qui peut renommer tous les fichiers d'un dossier en fonction d'une expression régulière ou d'autres critères. Ce que je recherche ici est dans mes documents de dossier, qui a disons 100 fichiers texte avec la convention de dénomination suivante:

<longdocumentidentifier>-doc-<counter>.txt.

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

doc-<counter>.txt

Y a-t-il une doublure qui peut m'aider avec ce qui précède?

50
sc_ray

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- avec doc-.

Si vous devez effectuer plusieurs remplacements (voir commentaire numéro 1), vous devez utiliser le ${var//Pattern/Replacement} une variante. Si vous devez remplacer le début du nom, vous devez utiliser ${var/#Pattern/Replacement}, si vous devez remplacer la fin (c'est-à-dire: l'extension), vous devez utiliser le ${var/%Pattern/Replacement} forme.

Voir http://tldp.org/LDP/abs/html/parameter-substitution.html#EXPREPL1 pour plus de détails

96
Sorin

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

21
telenachos

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

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

Utilisez l'option -n simuler:

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

Note: Il s'agit du rename fourni dans de nombreuses distributions Linux, mais pas dans toutes - donc j'utilise le nom canonique de l'utilitaire fourni avec Perl.

12
Elias Dorneles

La commande rename intégrée à la plupart des linux, par exemple, le fera facilement.

Personnellement, je préfère aussi les expressions régulières, c'est pourquoi je porte ce script depuis très 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 "Usage: $0 expr [files]]\n";

if(!@ARGV)
  {
  @ARGV = <STDIN>;
  chop(@ARGV);
  }

for (@ARGV)
  {
  $was = $_;
  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:

script-name 's/.*-doc(.*).txt/doc$1.txt/' *.txt
8
Wes Hardaker

Si vous souhaitez recurer dans des 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 automatiquement en charge les regexps étendus, vous pouvez laisser de côté le -E.

Avantages:

  • récursif 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)

Désavantages:

  • expressions rationnelles légèrement plus compliquées, car vous devez supprimer le chemin d'accès pour obtenir le nom du fichier

(réponse modifiée de ici )

5
Ron Wertlen
mmv "*-doc-*" "doc-#2"

la commande mmv signifie "mass move"

4
Ahmed

Si cela ne vous dérange pas l'outil externe, alors en voici un: rnm ( page web )

Pour votre problème particulier, la commande serait:

rnm -rs '/.*-doc-/doc-/' *.txt

Ou

rnm -rs '/.*-(doc-.*\.txt)/\1/' *.txt

Vous pouvez trouver plus d'exemples/documents ici .

3
Jahid

trouver . -name '* scss' | xargs -L1 -I {} echo {} {} | sed 's/css.scss $/scss /' | xargs -L1 mv

par exemple, si vous avez un tas de fichiers se terminant par ".css.scss" et que vous souhaitez les renommer pour se terminer par simplement ".scss" (c'est-à-dire supprimer la partie .css)

Ajustez l'expression rationnelle et trouvez des arguments selon vos besoins

0
John M Naglick