J'ai plusieurs fichiers (environ 1000) nommés comme tels:
abcdefg123456.xyz
abcdefg123457.xyz
abcdefg123458.xyz
abcdefg123459.xyz
Certains fichiers comportent 4 chiffres et lettres aléatoires supplémentaires (dans n'importe quel ordre) après le nom. Ce sont peut-être des doublons, mais pas toujours. Je dois donc les remplacer par le format d'origine pour vérifier s'ils sont en double ou non. Ils ont ce format:
abcdefg123456a789.xyz
abcdefg123457b987.xyz
abcdefg123458c879.xyz
abcdefg123459d897.xyz
À l’occasion, il existe également une mauvaise extension,
abcdefg123456.xyzedf
abcdefg123456.xyzfed
Je souhaite renommer ces fichiers au format original d'abcdefg suivi des 6 chiffres d'origine, c'est-à-dire supprimer les 4 chiffres et lettres aléatoires suivants et effacer l'extension finale .xyz Ce que j'ai pour l'instant est le suivant:
rename -n "s/[a-z][0-9]{6}.xyz/.xyz/g" *
Mais cela ne semble pas fonctionner. Pour une raison quelconque, le résultat est:
abcdef.xyz (no numbers)
EDIT: J'étais un peu déchiré entre quelle réponse choisir, parce que les deux ont aidé à trouver la solution. Je suis allé chercher des arguments, car il a également contribué à la deuxième partie de la question. Mais votre aide est également grandement appréciée, Mark Perryman - et les commentateurs également, bien sûr.
la source
{6}
chiffres: cela devrait être pour vos exemples{3}
. Pour supprimer des caractères supplémentaires après le,.xyz
vous devez ajouter.*
à la fin de la chaîne de correspondance, en donnantrename -n "s/[a-z][0-9]{3}\.xyz.*/.xyz/g" *
la commande (en omettant le-n
moment où vous êtes satisfait des actions)....a789.xyz
,...b987.xyz
mais suivent un schéma aléatoire au lieu:...a7b8.xyz
,...c9d7.xyz
. Merci.rename -n "s/[a-z][a-z0-9]{3}\.xyz.*/.xyz/g" *
fera. Sinon, vous ne pouvez pas simplement utiliser[a-z0-9]{4}
le modèle de correspondance, car cela supprimera les quatre derniers chiffres des fichiers au format standard et vous devrez utiliser des groupes de correspondance, comme dans les réponses, bien que vous puissiez essayerrename -n "s/[a-z0-9]{4}\.xyz.*/.xyz/g" ?????????????????.xyz*
(17 requêtes), qui ne devrait traiter que les noms de fichiers les plus longs. Notez la différence entre la correspondance d'expression régulière et l'expansion de fichier shell.Réponses:
Solution
Pour supprimer les 4 chiffres / lettres précédant l’arrêt complet de tous les fichiers, vous pouvez utiliser la boucle suivante:
Explication
Parcourt chaque fichier avec une extension .xyz
Créez une variable appelée
NEWFILE
contenant le nom du fichier après avoir supprimé un motif correspondant[a-z|0-9][a-z|0-9][a-z|0-9][a-z|0-9]
(mélange de 4 chiffres ou de lettres) et suivie d'un point final ((\.)
).Déplacez le fichier sous son nouveau nom,
-v
cela imprimera le processus de déplacement au format suivantCela ne couvre pas actuellement la réparation des extensions, mais une solution similaire à celle décrite ci-dessus peut être utilisée, mais avec la commande sed
sed 's/\.xyz.*/\.xyz/g'
.la source
abcdefg123456.xyz
format.(\.)
commande in the sed implique qu'il s'agit du modèle lettre / chiffre lettre / chiffre lettre / chiffre lettre / chiffre point final. Mes tests montrent que cela fonctionne. Existe-t-il des points d'arrêt complets dans les noms de fichiers autres qu'avant l'extension de fichier?for file in *.html ; do NEWFILE=$(echo "$file" |sed -re 's/([a-z]*[0-9]{6})[a-z0-9]{0,4}(\.html).*/\1\2/g'); mv -v $file $NEWFILE; done
Au moins, le test initial sur 50 fichiers semble donner de bons résultats. Je pense, bien que corrigez-moi si je me trompe, que les[a-z|0-9]
4 chiffres saisis avant de s'arrêter également, c’est pourquoi il modifie tous les fichiers originaux auabcdefg12
format.Essayer
Cela fonctionne sur la version de
rename
publiée avec debian et ubuntu (voir la page de manuel à http://www.computerhope.com/unix/rename.htm )Cela écrasera les fichiers qui auraient autrement des noms en double.
Pourquoi ça marche
([a-z]*[0-9]{6})
est l'abcdefg123456 capturé et peut être appelé$1
dans le remplacement.(\.xyz)
est l'extension capturée et appelée$2
dans le remplacement.[a-z0-9]{0,4}
(jusqu'à 4 lettres / chiffres) et.*
(tout ce qui suit l'extension) est mis en correspondance et ensuite ignoré dans le remplacement.Bonus Pour supprimer tous les fichiers qui ne correspondent toujours pas à votre modèle (par exemple, si vous n'avez pas utilisé l'option de force ci-dessus), utilisez-les
find
pour les lister et les supprimer. (Exécuter sans-exec rm {}
pour un essai à sec.)la source
.xyz
expression dans la recherche devrait être\.xyz
, bien.
qu'elle corresponde bien sûr à un littéral.
ainsi qu'à tout autre caractère. L'expression originale du questionneur fonctionnera comme vous le faites, mais uniquement sur les noms de fichier sans les caractères supplémentaires; les noms avec les caractères supplémentaires ne seront pas affectés.s/([a-z]*[0-9]{6})[a-z0-9]{0,4}(\.xyz).*/$1$2/g
?man rename
s'il existe uneforce
option ou similaire. Sinon, exécutez une commande distincte qui supprime les fichiers qui ne correspondent toujours pas au format. Quelque chose commefind . -regextype posix-egrep -regex '[a-z]*[0-9]{6}[a-z0-9]{4}\.xyz.*|[a-z]*[0-9]{6}\.xyz.*' -exec rm {}
mais RUN SANS-exec rm {}
PREMIER!No such file or directory
pour tous les fichiers (avec \ 1 \ 2 cela ferait le travail, tout en donnant les erreurs). La deuxième suggestion n'a rien fait. Je n'ai pas essayé de courir avec-exec rm {}