2 votes

Renommer des fichiers par lots en utilisant des expressions régulières sous Unix

J'ai plusieurs milliers de fichiers de ce type :

[numéro à 8 chiffres]_[numéro que je veux]_S60491_I129111.dcm.

Je souhaite tout supprimer sauf le numéro que je veux, et l'utiliser comme nom. En Ruby, je peux obtenir cette valeur avec l'expression régulière /^.*_(\d+)_S60491_I12911.dcm/ mais j'ai du mal à traduire cela en un fichier de type sed qui me permet de remplacer le nom de fichier complet par le nombre entre les caractères de soulignement.

Y a-t-il un moyen d'utiliser sed ou d'autres commandes Bash de base pour faire ce que je veux ? Si cela peut vous aider, le nombre que je veux n'est qu'un compteur (c'est-à-dire qu'il va de 1 à 2100), et le préfixe à 8 chiffres fait que les fichiers sont listés dans le bon ordre (c'est-à-dire du fichier 1 au fichier 2100), donc je pense peut-être trop.

2voto

Alex Points 962

Il existe un outil communément appelé renommer o prename installé sur la plupart des systèmes. Sur mes systèmes Debian/Ubuntu, il fait partie de Perl. Il vous permet d'utiliser des expressions régulières de style Perl pour manipuler les noms de fichiers comme vous le souhaitez.

Votre commande ressemblerait probablement à ceci. Je vous suggère de passer l'option --no-act et examinez la sortie avant de commit à faire des changements.

prename 's/^.*_(\d+)_S60491_I12911.dcm/$1/' *

1voto

Hennes Points 63532

Cela fonctionne pour moi : for a in * ; do mv "$a" $(echo "$a" | cut -d'_' -f 2) ; done

toad:/home/hennes/work/foo>ls -l
total 0
-rw-------  1   users  0 Jan 23 22:19 12345678\_023454\_S60491\_I129111.dcm
-rw-------  1   users  0 Jan 23 22:19 12345678\_123454\_S60491\_I129111.dcm
-rw-------  1   users  0 Jan 23 22:19 12345678\_123456\_S60491\_I129111.dcm

toad:/home/hennes/work/foo>for a in \* ; do mv $a $(echo $a | cut -d'\_' -f 2) ; done

toad:/home/hennes/work/foo>ls -l
total 0
-rw-------  1   users  0 Jan 23 22:23 023454
-rw-------  1   users  0 Jan 23 22:23 123454
-rw-------  1   users  0 Jan 23 22:23 123456

for a in * sélectionne tous les fichiers. S'il y a plus de fichiers, un *.dcm peut être utilisé à la place.

mv (déplacer) change le nom du fichier

à partir de $a (le nom du fichier sélectionné)

au champ2 du nom, avec _ a utilisé un délimiteur de champ.

Notez que ce script va déplacer les fichiers, donc les anciens noms de fichiers seront perdus. Vous pouvez utiliser 'cp' plutôt que 'mv' pour faire une copie à la place.

Si vous voulez garder l'extension, ajoutez-la après le -f 2).
Par exemple for a in * ; do cp $a $(echo $a | cut -d'_' -f 2).dcm ; done

1voto

Nicole Hamilton Points 9675

Puisque nous connaissons le format des noms et qu'aucun ne contient d'espace :

for a in * ; do
   mv $a $(echo $a | sed 's/[^_]*_//;s/_S60491_I129111.dcm//')
done

0voto

user114676 Points 166

Il existe de nombreuses façons d'y parvenir. Mais puisque vous avez demandé sed cela ferait l'affaire :

ls dcm | sed 's/^([0-9]{8}_([0-9] )_S60491_I129111.dcm)/mv \1 \2 /g' | bash

La première partie du modèle sélectionne les nombres à 8 chiffres, puis vous recherchez les chiffres quelconques (puisque vous n'avez pas mentionné la taille du deuxième nombre) et enfin votre séquence de queue. \1 y \2 se réfèrent au contenu des parenthèses échappées extérieures et intérieures \(...\) . Vous pouvez remplacer bash par tout Shell dans ce cas.

Les extensions GNU de sed vous permettraient de faire de même :

ls *dcm | sed 's/^([0-9]{8}_([0-9]+)_S60491_I129111.dcm)/mv \1 \2 /g' | bash

donde + permet de faire correspondre un ou plusieurs éléments, où * correspond à zéro ou plus, ce qui pose des problèmes pour 12345678__S60491_I129111.dcm .

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X