web-dev-qa-db-fra.com

Comment renommer plusieurs fichiers séquentiellement à partir de la ligne de commande?

Comment renommer le fichier comme ci-dessous

AS1100801000002.RAW7AGS 
AS1100801001008.RAW7AH4
AS1100801002001.RAW7AH9
AS1100801003002.RAW7AHE
AS1100801004009.RAW7AHT
AS1100801005002.RAW7AHY
AS1100801010002.RAW7AJ3

à nouveau nom

AS1.txt
AS2.txt
AS3.txt
AS4.txt
AS5.txt
AS6.txt
AS7.txt
15
kamaruz85

L'outil rename fourni avec Ubuntu est très prisé dans ce genre de choses. Vous pouvez intégrer de petites expressions Perl comme ceci:

rename -n 's/.+/our $i; sprintf("AS%d.txt", 1+$i++)/e' *

Cela vous montrera simplement ce que cela ferait. Supprimez le -n pour en faire un exercice de tir réel.

Cela fonctionne essentiellement en définissant grossièrement une variable et en l'incrémentant à chaque fichier que nous consultons. Si vous avez plus de 10 fichiers, je vous suggère d’utiliser du zéros dans le sprintf. Ce qui suit est bon jusqu'à 999:

rename -n 's/.+/our $i; sprintf("AS%03d.txt", 1+$i++)/e' *

... Mais c'est assez facile à développer.

21
Oli

Je ne connais pas de commande ou d'utilitaire qui ferait cela, mais c'est assez facile à faire avec une simple boucle:

N=1
for X in AS*RAW*; do
  mv $X AS$N.txt
  N=$(($N+1))
done
4
Paul

Pour améliorer @ (Oli) answer , l'outil renameversion 1.6 by Aristotle Pagaltzis a en fait un compteur intégré, $N.

Donc tout ce dont vous avez besoin c'est

rename 's/AS.*/AS$N/' *

À installer,

  1. brew install rename or Téléchargez le script
  2. Enregistrez-le dans un répertoire de votre chemin système (généralement /usr/local/bin/brew ou /usr/bin)
3
Atav32

rename vous permet d'affecter directement à $_, ce qui est idéal pour résoudre ce problème.

Bien que les arguments de code que nous passons à l'utilitaire Perl rename effectuent souvent la correspondance et la substitution (avec s/), et c'est totalement acceptable to résout ce problème de cette façon , cela n’est vraiment pas nécessaire dans des cas comme celui-ci où vous n’examinez pas ou ne réutilisez pas le texte des anciens noms de fichiers. rename vous permet d'écrire à peu près tous les codes Perl, et il n'a pas besoin d'être incorporé dans s//e. Je suggère d'utiliser une commande comme celle-ci:

rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' *

Ou, si vous avez envie de raser quelques personnages:

rename -n '$_ = sprintf "AS%02d.txt", ++our$i' *

(Cela pourrait être encore plus court, mais pas sans sacrifier la clarté.)

Ces deux commandes font la même chose. Chacun montre quelles opérations de changement de nom seraient entreprises. Une fois que vous en avez essayé un et que vous êtes satisfait du résultat, exécutez-le à nouveau sans l'option -n. Comme cela est écrit, cela produirait les noms de fichier AS01.txt, AS02.txt, ..., AS10.txt, AS11.txt, etc. Vous pouvez les modifier en fonction de vos besoins, puis supprimez -n uniquement lorsque vous aimez ce que vous voyez.

Si vous souhaitez utiliser une largeur supérieure à 2, remplacez le 2 par un nombre plus élevé. Par exemple, si, pour une raison quelconque, vous souhaitez utiliser des noms de fichier tels que AS00000000000001.txt, vous devez remplacer %02d par %014d. Si vous ne voulez pas du tout de rembourrage (même si cela ferait que vos fichiers apparaîtront dans un ordre non numérique lorsque vous les listerez plus tard!), Vous pouvez alors remplacer %02d par juste %d.

Comment cela marche-t-il? Votre shell se déploie* dans une liste de fichiers avant même d'exécuter la commande rename. La liste est triée lexicographiquement (c'est-à-dire par ordre alphabétique) en fonction de vos paramètres régionaux actuels. rename reçoit les noms de fichiers sous forme d'arguments de ligne de commande et les traite dans l'ordre indiqué. L'expression ++$i correspond à une valeur supérieure à la valeur actuelle de la variable $i et définit également la variable $i sur cette valeur nouvellement incrémentée. Cette valeur est transmise à sprintf , qui la formate et la place dans un autre texte. Ce texte est directement affecté à la variable spéciale $_, qui contient le nom du fichier. Étant donné que rename traite les fichiers dans leur ordre d’argument, ils sont numérotés en conséquence.


Vous avez peut-être remarqué la similitude avec Oli's réponse !

Les deux déclarent et incrémentent une variable de compteur et utilisent sprintf de manière essentiellement identique pour incorporer la valeur de ce compteur, complétée à gauche par des zéros, dans l'autre texte du nouveau nom de fichier. (L'information dans l'une ou l'autre réponse sur la manière de remplir avec des zéros - et de changer la largeur de remplissage - s'applique même aux deux.) La raison pour laquelle ils sont si similaires est que la méthode de cette réponse plus ancienne est en train de le faire. 1 , mais avec des étapes supplémentaires utiles pour de nombreux problèmes mais pas vraiment nécessaires pour celui-ci.

À titre de comparaison, voici à quoi ressemble la deuxième commande de cette réponse si elle est modifiée pour utiliser le style que j'ai utilisé ici (et pour appliquer une largeur de 2, comme je l'ai fait ici, au lieu de 3):

rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' *

La partie entre s/.+/ et /e dans cette commande est maintenant identique à l'expression que j'attribue à $_ (c'est-à-dire le code situé à droite de l'opérateur = dans la première commande de cette réponse.

  • s/operator tente de faire correspondre le texte (les noms de fichier développés par votre Shell à partir de * et transmis sous forme d'arguments de ligne de commande lors de l'exécution de rename) avec un expression régulière et effectue une substitution. / est utilisé comme délimiteur pour séparer les différentes parties de l'expression s. La première partie, .+, est l'expression régulière. il correspond à tout 1  character (.) , et le fait une ou plusieurs fois (+) . Comme les noms de fichiers ne sont jamais vides - ils ont toujours au moins un caractère - c’est un moyen de faire correspondre tout 1  nom de fichier.
  • Ensuite, il produit le texte de chaque correspondance, c'est-à-dire de chaque nom de fichier complet, constitué de our $i; sprintf "AS%02d.txt", ++$i. Cela produit le nouveau nom de fichier. Généralement, on utilise s/ pour produire du texte qui est (a) et remplace le texte qui correspond uniquement à une partie du nom de fichier, ou (b) basé sur le texte correspondant d'une certaine manière (par exemple, il peut utiliser une variable spéciale telle que $& qui se développe en correspondance). Dans ce cas, cependant, le texte correspondant n'est pas utilisé du tout.
  • Normalement, le texte substitué our $i; sprintf "AS%02d.txt", ++$i serait utilisé comme nom de fichier, et non exécuté comme code. Mais le drapeau /e à la fin fait que ce texte soit traité comme un code source Perl et évalué, et utilise la valeur ainsi générée (dans ce cas, la valeur de retour de la fonction intégrée sprintf de Perl) en tant que nouveau nom de fichier.

Bien que je pense que la méthode que j'ai montrée ici est une approche plus claire et plus simple de ce problème que toute méthode qui utilise s/ avec /e, il est bon de connaître cette technique, car il est bien adapté à un certain nombre d'autres problèmes de changement de nom de fichier dans lesquels tout ou partie des noms de fichier d'origine sont examinés et/ou conservés. Je recommande cet article par Oli (qui a également écrit cette réponse ) , qui inclut quelques exemples.

1 Techniquement, il existe une différence dans le comportement des commandes $_ = et des commandes s//e. Dans l'expression régulière .+, il n'est pas strictement vrai que . correspond à n'importe quel caractère , car il ne correspond pas à un newline . Vous ne devriez probablement pas utiliser de noms de fichiers contenant des retours à la ligne, mais vous pouvez le faire, et il arrive parfois qu'un fichier soit ainsi nommé par accident. Si vous en avez envie, comparez le résultat de rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' $'foo\nbar' avec celui de rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' $'foo\nbar'. Pour que . corresponde à une nouvelle ligne, utilisez l'indicateur s, qui se place à la fin (avec e). Autrement dit, écrivez /se à la fin au lieu de /e.

2
Eliah Kagan

Bien que l'OP nécessite une option de ligne de commande, il est également disponible comme option d'interface graphique dans Nautilus et est assez simple.

Sélectionnez tous les fichiers requis et appuyez sur F2. Il existe une option appelée Numéros automatiques. Vous pouvez l'ajouter au texte dont vous avez besoin.

0
Sandeep C

Supposons que les fichiers que vous souhaitez renommer se trouvent dans ~/Adir, et que ce soient les seuls fichiers de ce dossier, puis:

n=0
for f in $( ls ~/Adir | sort ) ; do
    n=$(( n+1 ))
    mv -n "$f" "AS${n}.txt"
done

Ce script examinera chaque fichier dans ~/Adir et le renommera en AS1.txt, AS2.txt, ... si le fichier n’existe pas (il n’y aura pas de réécriture). C'est pourquoi vous devez vous assurer que ce sont les seuls fichiers dans ~/Adir. La commande sort est juste au cas où vous voudriez que les fichiers conservent la commande initiale.

0
edwin