6 votes

Aide avec Bash script - ajout de numéros séquentiels

Je suis assez novice en matière de scripting bash et j'espère que quelqu'un pourra m'aider.

J'ai des dossiers qui contiennent des images nommées ainsi :

file_001.jpeg  
file_002.jpeg  
file_003.jpeg  

J'essaie d'écrire une fonction bash qui prend deux arguments et renomme les fichiers comme ceci :

photo-argument1-argument2_001.jpeg  

par exemple

photo-christmas-2014_001.jpeg  

Voici ce que j'ai :

function rename () {
  title="photo"
  h="-"
  u="_"
  new=$title$h$1$h$2$u
  for file in *.jpeg; do
    mv -v "$file" "$new"
  done
}

donc en cours d'exécution rename birthday 2015 produit photo-birthday-2015_ ,par exemple.

Il y a juste un problème : comment ajouter des chiffres au nouveau nom de fichier ? Soit j'extrais les numéros existants dans le nom de fichier, soit j'en génère de nouveaux, mais quelle est la meilleure méthode, la plus simple, et comment dois-je m'y prendre ?

8voto

Zanna Points 65764

Vous pouvez demander à bash de compter pour vous en lui indiquant où commencer, comme ceci :

$ n=0
$ echo $((++n))
1
$ echo $((++n))
2
$ echo $((++n))
3

Vous pouvez utiliser printf %03d pour formater le résultat de $((++n)) como 001 002 003 et 010 , 011 etc., pour un tri plus précis. De même, il est inutile de définir - et _ comme des variables puisqu'elles ne vont pas varier. Votre fonction pourrait être la suivante :

function rename () {
  title="photo"
  n=0
  for file in *.jpeg; do
   printf -v new "$title-$1-$2_%03d.jpeg" "$((++n))"
   mv -v -- "$file" "$new"
  done
}

Ce qui est le cas :

$ rename birthday 2015
'file_001.jpeg' -> 'photo-birthday-2015_001.jpeg'
'file_002.jpeg' -> 'photo-birthday-2015_002.jpeg'
'file_003.jpeg' -> 'photo-birthday-2015_003.jpeg'

Mais il y a déjà une utile rename dans Ubuntu, vous pouvez donc utiliser un autre nom :)

3voto

jiipeezz Points 1236

Ce que j'ai compris, c'est que vous voulez juste ajouter des numéros séquentiels à la fin. Je ferais personnellement ceci

 function rename () {
  count=1           #The first photo will get number 1 to the end
  title="photo"
  h="-"
  u="_"
  new=$title$h$1$h$2$u
  for file in *.jpeg; do
    if [ $count -lt 10 ]; then
        mv -v "$file" "${new}00$count" #numbers 1-9 will be like 001 002..
    elif [ $count -lt 100 ]; then
        mv -v "$file" "${new}0$count" #numbers 10-99 like 022 056 etc..
    else
        mv -v "$file" "$new$count"
    fi
    count=$[ $count + 1 ]      #count variable gets bigger by one 
  done
}

Lorsque les fichiers sont renommés, ils obtiennent des numéros séquentiels avec un remplissage à la fin. Cela pourrait être fait différemment comme indiqué dans d'autres réponses, mais je trouve que c'est assez facile à comprendre dans le cas où une personne n'a pas une très bonne connaissance des scripts bash.

J'espère que cela vous aidera !

3voto

Sergiy Kolodyazhnyy Points 97292

Une alternative Python un peu longue mais utilisable. En supposant que votre nommage est cohérent avec ce que vous avez dans l'exemple, vous pourriez utiliser cette fonction dans votre fichier ~/.bashrc . ( Faites attention aux caractères "\". Il ne doit pas y avoir d'espace après, seulement une nouvelle ligne.)

rename_photos()
{
    python -c 'import os,re,sys; \
    [ os.rename(f, "photo_"+sys.argv[1]+\
      "_"+sys.argv[2]+"_"+re.split("[_.]",f)[-2]+\
      "."+re.split("[_.]",f)[-1])  \
      for f in os.listdir(".") \
    ]' "$1" "$2"
}

Et appelez comme

rename_photos arg1 arg2

En supposant que votre nommage est cohérent, ce que cela fait est de séparer le nom de fichier en parties à "." et "_" et de les renommer via os.rename fonction

Par exemple :

$ ls
file_001.jpeg  file_002.jpeg  file_003.jpeg
$ rename_photos birthday 2016
$ ls
photo_birthday_2016_001.jpeg  photo_birthday_2016_002.jpeg  photo_birthday_2016_003.jpeg

Version du script

Sans le rendre trop complexe, voici un petit script qui fait la même fonction. Il y a beaucoup de commentaires pour expliquer ce que fait chaque partie. Le script lui-même doit être stocké dans l'un des répertoires qui font partie de votre répertoire $PATH par exemple dans votre ~/bin dossier. Sinon, il exécute exactement la même fonction (en plus d'imprimer les nouveaux noms de fichiers).

#!/usr/bin/env python
import os
import re
import sys

# The operates on all files in the current working
# directory, so you would have to cd to your folder
# and run script there. 
for item in os.listdir("."):

    # We don't wanna rename the script itself ( just in case ) and
    # we don't
    if os.path.join("./" + item) != __file__ and \
       os.path.isfile("./" + item):
           title="photo_"

           # Old name can be split into parts using _ and . as 
           # separators, so we only take items between those as one.
           # The last item (-1) is extension, and the one
           # before extension is number
           old_name = re.split("[_.]",item)
           new_name = sys.argv[1] + sys.argv[2] + "_" \
                      + old_name[-2] + "." + old_name[-1]

           print(new_name)
           os.rename(item,new_name)

1voto

anon Points 11

Vous pouvez décider par vous-même quelle est la voie la plus facile.

Extraction des anciens numéros

Vous pouvez obtenir les numéros dans votre nom de fichier avec une commande comme grep :

number=$(egrep -o '[0-9]+' <<< "$file")

La commande ci-dessus enregistre toute séquence de chiffres (correspondant au motif '[0-9]+') dans le fichier de variables (transmis à grep par le biais de <<< ) au numéro de la variable.

Générer de nouveaux numéros

Vous pouvez essayer quelque chose comme ci-dessous :

number=0 # initialize number to 0
for file in *.jpeg; do
    ... # do some stuff here
    ((number+=1)) # adds 1 to the variable number
done

Cela génère un numéro à partir de 0 pour chacun de vos fichiers.

Il peut être utile d'avoir des nombres formatés avec une largeur fixe (c'est-à-dire 001 au lieu de 1) à des fins de tri. Dans ce cas, vous pouvez utiliser printf pour obtenir la sortie souhaitée :

number_formatted="$(printf "%03d" "$number")"

Le code ci-dessus formate "12" comme "012" et "321" comme "321". Le "%03d" spécifie le format (0 signifie ajouter 0 au nombre, 3 spécifie 3 chiffres au total, y compris les 0).

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