web-dev-qa-db-fra.com

Comment supprimer des caractères de noms de fichiers en utilisant la ligne de commande?

J'ai un tas de fichiers nécessitant un changement de nom mais je ne veux pas créer de script pour cela, juste une ligne de commande.

Je dois supprimer les derniers chiffres entre le . et le .gif:

22771786_01.204.gif  
22771786_02.203.gif  
22771786_03.10.gif  
22771786_04.56.gif

Pour être comme ça:

22771786_01.gif  
22771786_02.gif  
22771786_03.gif  
22771786_04.gif
3
a.v

Vous pouvez y parvenir avec une boucle for et quelques extensions bash. Si vous êtes déjà dans le répertoire contenant les fichiers:

for f in ./*; do mv "$f" "${f%.*.gif}.gif" ; done

Si votre répertoire contenant les fichiers s'appelle/home/gifstore /:

for f in /home/gifstore/*; do mv "$f" "${f%.*.gif}.gif" ; done

Le ${f...} développe chaque nom de fichier que nous avons enregistré dans la variable nommée f. Le % dans le développement du nom de fichier signifie que l’on supprime la correspondance la plus courte du modèle suivant à la fin de la variable. Le modèle est .*.gif, ce qui signifie toute quantité de caractères comprise entre . et .gif. Enfin, nous ajoutons la chaîne littérale .gif en dehors de l’extension pour créer notre nouveau nom de fichier, et nous nous appuyons sur la commande mv pour déplacer le fichier.

Cela ne fonctionnera pas pour les fichiers cachés, en commençant par ..

6
Arronical

La commande rename (vous pouvez également l'exécuter en tant que file-rename) convient bien à cette tâche. Il y a plusieurs façons de l'utiliser ici. Je suggère ceci, bien que je montre une alternative ci-dessous:

rename -n 's/^\d{8}_\d\d\K\.\d+//' *.gif

L'option -n permet simplement d'imprimer quelles opérations de changement de nom seraient une première. Une fois que cela vous convient, lancez-le à nouveau sans -n pour renommer. L'un des avantages de rename est qu'il ne remplacera pas les fichiers. (sauf si vous passez l'option -f, ce que vous devriez faire très rarement). Cela est particulièrement utile ici, car vous supprimez des noms de fichiers des parties pouvant potentiellement entraîner des collisions de noms. Même si les collisions ne sont pas détectées lors de la simulation avec -n, elles seront interceptées lors de la modification du nom.

Avec les quatre fichiers que vous avez montrés, cette commande affichera cette sortie:

rename(22771786_01.204.gif, 22771786_01.gif)
rename(22771786_02.203.gif, 22771786_02.gif)
rename(22771786_03.10.gif, 22771786_03.gif)
rename(22771786_04.56.gif, 22771786_04.gif)

Bien entendu, votre sortie sera plus longue si vous avez plus de quatre fichiers, ce que je suppose que vous avez.


La façon dont cette commande fonctionne est que s/ effectue une substitution. Les noms de fichiers contenant du texte correspondant à expression régulière^\d{8}_\d\d\K\.\d+ sont modifiés de sorte que la correspondance soit supprimée, c'est-à-dire remplacée par la chaîne vide comprise entre / et / dans le // qui suit.

Bien que l'expression régulière puisse être écrite de manière à garantir que seuls les fichiers se terminant par .gif sont utilisés, cela est inutile, car vous pouvez simplement transférer les noms de fichier .gif à rename. Le shell développe *.gif en une liste de ces fichiers et la transmet à la commande rename. Notez que la syntaxe utilisée par le shell pour expansion du nom de fichier est pas la même chose que expressions régulières . * n'a pas la même signification que dans les expressions régulières.

Voici ce que fait l'expression régulière ^\d{8}_\d\d\K\.\d+:

  • ^ancres au début de la ligne.
  • \d{8} correspond à ne séquence de exactement huit chiffres .
  • _ correspond à un _ littéral. Ce n'est pas spécial.
  • \d\d correspond à deux autres chiffres.
  • \Koublie les caractères correspondants précédents . Ce sont les personnages que nous voulons conserver, après tout, pas ceux que nous voulons remplacer. L’effet est d’assurer que ces caractères sont présents juste avant la partie que nous allons réellement remplacer.
  • \. correspond à un . littéral. La barre oblique inverse est nécessaire car sinon, lorsqu'un point apparaît dans une expression régulière, correspond à any caractère unique .
  • \d+ correspond à un ou plusieurs chiffres .

Il s’agit donc d’un . suivi de chiffres qui sont supprimés. Si le fichier ne commence pas par le motif nécessaire, il n'y a pas de correspondance. Cela évite de renommer des fichiers que vous ne souhaitez pas renommer.

Il est possible d'écrire une commande rename plus courte qui devrait fonctionner. J'ai choisi cette approche - parmi many = approches possibles - car la commande exprime précisément le schéma de dénomination sur lequel vous souhaitez opérer. C'est-à-dire que la solution ressemble au problème.


Si vous souhaitez utiliser une commande plus simple rename et que vous savez que tous les fichiers .gif du répertoire actuel sont nommés en fonction de votre description et doivent être renommés, vous pouvez utiliser:

rename -n 's/\.\d+\.gif$/\.gif/' *

Rappelez-vous que -n vous indique simplement ce qui sera fait et vous devez ensuite le supprimer pour renommer les fichiers.

Dans cette commande, j'ai inclus le suffixe .gif dans l'expression régulière afin que vous n'ayez pas à le filtrer dans les noms de fichiers passés à rename. Néanmoins, vous pouvez choisir de le faire si le répertoire en cours contient de nombreux fichiers non -.gif qui correspondraient inutilement à *.

Voici ce que fait l'expression régulière \.\d+\.gif$:

  • \. correspond à un . littéral. (Sans le \, un . correspond à n'importe quel caractère .)
  • \d+ correspond à un ou plusieurs chiffres .
  • \. correspond à un autre littéral ..
  • gif correspond au texte littéral gif.
  • $ancres la correspondance avec le end du nom du fichier.

Ainsi, le point, les derniers chiffres et le suffixe .gif sont appariés et tous remplacés par juste .gif.

1
Eliah Kagan

Personnellement, j’aime utiliser ranger pour ce type de choses. Il utilise les combinaisons de touches de Vim pour la navigation et autres, donc si vous n'êtes pas familier avec vim, cela pourrait devenir confus/difficile. Mais si vous connaissez déjà Vim, cela devrait être une tâche simple!

Étape 1

Installez rangername__. Vous pouvez l'installer en tant que plugin Vim ou simplement télécharger le fichier .tar.gz à partir du site web .

Étape 2

Exécutez Ranger et accédez au répertoire contenant les fichiers que vous souhaitez renommer. Je recommanderais de mettre tous les fichiers .gifs dans un répertoire. Assurez-vous qu'il n'y a pas d'autres fichiers à l'exception de ceux que vous souhaitez renommer.

Étape 3

Appuyez sur vpour sélectionner tous les fichiers.

Étape 4

tapez :bulkrename et appuyez sur Entername__

Étape 5

Utilisez une macro Vim pour enregistrer les modifications que vous souhaitez apporter. Donc, pour votre exemple, si vous avez commencé à la toute première ligne du fichier, vous utiliseriez ces commandes:

q a (cela démarre la macro nommée "a")

0, f., de(déplace le curseur au début de la ligne, trouve le premier ".", puis efface le dernier caractère avant le deuxième "." avant gif)

q(pour arrêter l'enregistrement de la macro)

Étape 6

Passez à la deuxième ligne et déplacez le curseur au début de la ligne (jname __, 0) et tapez :2,$norm! @a

Cela exécutera la macro que vous venez de créer (nommée "a") à partir de la deuxième ligne jusqu'à la fin du fichier.

Étape 7

:wq pour enregistrer et quitter, puis :wq pour confirmer les modifications.


Donc, si tout se passe bien, vous devriez avoir renommé tous vos fichiers. Si vous n'avez jamais utilisé Vim auparavant, je vous recommanderais d'utiliser une autre réponse afin de ne pas avoir à apprendre Vim pour renommer des fichiers. Je préfère utiliser Vim, c'est donc ma méthode de choix pour renommer en bloc.

1
RandomlyRainy