web-dev-qa-db-fra.com

Renommer des fichiers à l'aide d'une expression régulière sous Linux

J'ai un ensemble de fichiers nommés comme:

Friends - 6x03 - Tow Ross' Denial.srt
Friends - 6x20 - Tow Mac and C.H.E.E.S.E..srt
Friends - 6x05 - Tow Joey's Porshe.srt

et je veux les renommer comme suit

S06E03.srt
S06E20.srt
S06E05.srt

que dois-je faire pour faire le travail dans un terminal linux? J'ai installé renommer mais U obtient des erreurs en utilisant ce qui suit:

rename -n 's/(\w+) - (\d{1})x(\d{2})*$/S0$2E$3\.srt/' *.srt
39
orezvani

Vous avez oublié un point devant l'astérisque:

rename -n 's/(\w+) - (\d{1})x(\d{2}).*$/S0$2E$3\.srt/' *.srt

Sur OpenSUSE, RedHat, Gentoo, vous devez utiliser la version Perl de rename. Cette réponse montre comment l'obtenir. Sur Arch, le package est appelé Perl-rename.

56
Thor

Lil diddy vraiment cool. trouver + Perl + xargs + mv

xargs -n2 permet d'imprimer deux arguments par ligne. Lorsqu'il est combiné avec Perl's print $_ (pour imprimer le $ STDIN en premier), il constitue un puissant outil de renommage.

find . -type f | Perl -pe 'print $_; s/input/output/' | xargs -n2 mv

Resultats de Perl -pe 'print $_; s/OldName/NewName/' | xargs -n2 finir par être:

OldName.ext    NewName.ext
OldName.ext    NewName.ext
OldName.ext    NewName.ext
OldName.ext    NewName.ext

Je n'avais pas de rename de Perl facilement disponible sur mon système.


Comment ça marche?

  1. find . -type f affiche les chemins de fichiers (ou les noms de fichiers ... vous contrôlez ce qui est traité par regex ici!)
  2. -p imprime les chemins de fichiers qui ont été traités par regex, -e exécute un script en ligne
  3. print $_ imprime d'abord le nom du fichier d'origine (indépendamment de -p)
  4. -n2 imprime deux éléments par ligne
  5. mv obtient l'entrée de la ligne précédente
8
Jonathan Komar

Modifier: a trouvé une meilleure façon de lister les fichiers sans utiliser IFS et ls tout en étant sh conforme.

Je ferais un script Shell pour ça:

#!/bin/sh
for file in *.srt; do
  if [ -e "$file" ]; then
    newname=`echo "$file" | sed 's/^.*\([0-9]\+\)x\([0-9]\+\).*$/S0\1E\2.srt/'`
    mv "$file" "$newname"
  fi
done

Script précédent:

#!/bin/sh
IFS='
'
for file in `ls -1 *.srt`; do
  newname=`echo "$file" | sed 's/^.*\([0-9]\+\)x\([0-9]\+\).*$/S0\1E\2.srt/'`
  mv "$file" "$newname"
done
8
Creak

Toutes les distributions ne livrent pas un utilitaire rename qui prend en charge les expressions rationnelles telles qu'utilisées dans les exemples ci-dessus - RedHat, Gentoo et leurs dérivés entre autres.

Les alternatives à essayer sont Perl-rename et mmv.

7
gerrit_hoekstra

Utilisez mmv (mouvement de masse?)

C'est simple mais utile: il utilise * pour n'importe quelle chaîne et ? pour n'importe quel caractère de la chaîne de correspondance et #X dans la chaîne de remplacement pour faire référence à la X-ème correspondance.

Dans ton cas:

mmv 'Friends - 6x?? - Tow *.srt' 'S06E#1#2.srt'

Ici #1#2 représente les deux chiffres capturés par ?? (correspond aux n ° 1 et n ° 2).
Le remplacement suivant est donc effectué:

Friends - 6x?? - Tow *           .srt    matches
Friends - 6x03 - Tow Ross' Denial.srt    which is replaced by
            ↓↓
        S06E03.srt

mmv propose également une correspondance par [ et ] et ;.

Vous pouvez non seulement renommer , mais aussi déplacer, copier, ajouter et lier les fichiers .

Lisez la page de manuel liée ci-dessus pour en savoir plus!

Personnellement, je l'utilise pour remplir les nombres de telle sorte que les fichiers numérotés apparaissent dans l'ordre souhaité lorsqu'ils sont triés lexicographiquement: file_?.extfile_0#1.ext

5
xoxox

si votre Linux ne propose pas renommer , vous pouvez également utiliser ce qui suit:

find . -type f -name "Friends*" -execdir bash -c 'mv "$1" "${1/\w+\s*-\s*(\d)x(\d+).*$/S0\1E\2.srt}"' _ {} \;

j'utilise cet extrait assez souvent pour effectuer des substitutions avec regex dans ma console.

je ne suis pas très bon dans Shell-stuff, mais pour autant que je comprends ce code, son explication serait comme: les résultats de recherche de votre find être passé à une commande bash ( bash -c ) où votre résultat de recherche sera à l'intérieur de $ 1 comme fichier source. la cible qui suit est le résultat d'une substitution dans un sous-shell, où le contenu de $ 1 (ici: juste 1 à l'intérieur de votre paramètre-substitution {1 // find/replace} ) sera être également votre résultat de recherche. le {} le transmet au contenu de - execdir

de meilleures explications seraient grandement appréciées :)

s'il vous plaît noter: je copie seulement votre regex; veuillez d'abord le tester avec des fichiers d'exemple. en fonction de votre système, vous devrez peut-être remplacer\d et\w par des classes de caractères telles que [[: digit:]] ou [[: alpha:]]. cependant,\1 devrait fonctionner pour les groupes.

1
meistermuh

Vous pouvez utiliser rnm :

rnm -rs '/\w+\s*-\s*(\d)x(\d+).*$/S0\1E\2.srt/' *.srt

Explication:

  1. -rs: remplace la chaîne de la forme /search_regex/replace_part/modifier
  2. (\d) et (\d+) dans (\d)x(\d+) sont deux groupes capturés (\1 et \2 respectivement).

Plus d'exemples ici .

0
Jahid