Question

Quel est le meilleur moyen, à l'aide de Bash, de renommer des fichiers sous la forme:

(foo1, foo2, ..., foo1300, ..., fooN)

Avec des zéros noms de fichiers:

(foo00001, foo00002, ..., foo01300, ..., fooN)
Était-ce utile?

La solution

En cas N n'est a priori pas fixe:

 for f in foo[0-9]*; do mv $f `printf foo%05d ${f#foo}`; done

Autres conseils

Il n'est pas pur bash, mais beaucoup plus facile avec l' rename commande:

rename 's/\d+/sprintf("%05d",$&)/e' foo*

J'ai eu un cas plus complexe où les noms de fichier avait un postfix ainsi que d'un préfixe.J'ai également nécessaire d'effectuer une soustraction sur le nombre de nom de fichier.

Pour exemple, j'ai voulu foo56.png pour devenir foo00000055.png.

J'espère que cette aide si vous êtes en train de faire quelque chose de plus complexe.

#!/bin/bash

prefix="foo"
postfix=".png"
targetDir="../newframes"
paddingLength=8

for file in ${prefix}[0-9]*${postfix}; do
  # strip the prefix off the file name
  postfile=${file#$prefix}
  # strip the postfix off the file name
  number=${postfile%$postfix}
  # subtract 1 from the resulting number
  i=$((number-1))
  # copy to a new name with padded zeros in a new folder
  cp ${file} "$targetDir"/$(printf $prefix%0${paddingLength}d$postfix $i)
done

Le oneline de commande que j'utilise est ceci:

ls * | cat -n | while read i f; do mv "$f" `printf "PATTERN" "$i"`; done

MOTIF peut être par exemple:

  • renommer avec un incrément du compteur: %04d.${f#*.} (maintenir l'extension du fichier original)
  • renommer avec un incrément du compteur avec le préfixe: photo_%04d.${f#*.} (garder l'original de l'extension)
  • renommer avec un incrément du compteur et de changer l'extension des fichiers jpg: %04d.jpg
  • renommer avec un incrément du compteur avec le préfixe et le fichier basename: photo_$(basename $f .${f#*.})_%04d.${f#*.}
  • ...

Vous pouvez filtrer les fichiers à renommer avec par exemple ls *.jpg | ...

Vous avez à disposition la variable f c'est le nom de fichier et i c'est le compteur.

Pour votre question, le droit de la commande est:

ls * | cat -n | while read i f; do mv "$f" `printf "foo%d05" "$i"`; done

Pur Bash, pas de processus externe, autre que "mv":

for file in foo*; do
  newnumber='00000'${file#foo}      # get number, pack with zeros
  newnumber=${newnumber:(-5)}       # the last five characters
  mv $file foo$newnumber            # rename
done

La suite va le faire:

for ((i=1; i<=N; i++)) ; do mv foo$i `printf foo%05d $i` ; done

EDIT: changé à utiliser ((i=1,...)), merci mweerden!

Voici une solution rapide qui suppose un préfixe de longueur fixe (votre "foo") et de longueur fixe de rembourrage.Si vous avez besoin de plus de souplesse, peut-être que ce sera au moins un point de départ utile.

#!/bin/bash

# some test data
files="foo1
foo2
foo100
foo200
foo9999"

for f in $files; do
    prefix=`echo "$f" | cut -c 1-3`        # chars 1-3 = "foo"
    number=`echo "$f" | cut -c 4-`         # chars 4-end = the number
    printf "%s%04d\n" "$prefix" "$number"
done

Ma solution remplace les nombres, partout dans une chaîne de caractères

for f in * ; do
    number=`echo $f | sed 's/[^0-9]*//g'`
    padded=`printf "%04d" $number`
    echo $f | sed "s/${number}/${padded}/";
done

Vous pouvez facilement essayer, car il imprime juste transformé les noms de fichiers (pas de système de fichiers sont les opérations réalisées).

Explication:

En parcourant la liste des fichiers

Une boucle: for f in * ; do ;done, répertorie tous les fichiers et passe chaque nom de fichier $f variable de corps de boucle.

En saisissant le numéro de chaîne

Avec echo $f | sed nous tuyau variable $f pour sed programme.

Dans la commande sed 's/[^0-9]*//g', la partie [^0-9]* avec le modificateur ^ dit pour correspondre à l'opposé de chiffres de 0 à 9 (pas un nombre) et retirez-la ensuite avec vide de remplacement //.Pourquoi ne pas simplement supprimer [a-z]?Parce que le nom de fichier peut contenir des points, des tirets, etc.Donc, nous dépouiller de tout, qui n'est pas un nombre et un nombre.

Ensuite, nous avons affecter le résultat de number variable.Rappelez-vous de ne pas mettre des espaces dans l'affectation, comme number = …, parce que vous obtenez un comportement différent.

Nous affecter résultat de l'exécution d'une commande à une variable, emballage de la commande avec backtick de symboles.

Zéro de remplissage

Commande printf "%04d" $number les changements de format d'un nombre à 4 chiffres et ajoute des zéros si notre numéro contient moins de 4 chiffres.

Remplacement nombre de zéros nombre

Nous utilisons sed de nouveau avec remplacement de la commande comme s/substring/replacement/.Pour interpréter nos variables, nous utilisons des guillemets, et remplacer les variables de cette manière ${number}.


Le script ci-dessus imprime juste transformé noms, alors, faisons-le réel de renommage de l'emploi:

for f in *.js ; do
    number=`echo $f | sed 's/[^0-9]*//g'`
    padded=`printf "%04d" $number`
    new_name=`echo $f | sed "s/${number}/${padded}/"`
    mv $f $new_name;
done

Espérons que cela aide quelqu'un.

J'ai passé plusieurs heures à le comprendre.

À gauche de la tablette nombres dans les noms de fichiers:

$ ls -l
total 0
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:24 010
-rw-r--r-- 1 victoria victoria 0 Mar 28 18:09 050
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:23 050.zzz
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:24 10
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:23 1.zzz

$ for f in [0-9]*.[a-z]*; do tmp=`echo $f | awk -F. '{printf "%04d.%s\n", $1, $2}'`; mv "$f" "$tmp"; done;

$ ls -l
total 0
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:23 0001.zzz
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:23 0050.zzz
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:24 010
-rw-r--r-- 1 victoria victoria 0 Mar 28 18:09 050
-rw-r--r-- 1 victoria victoria 0 Mar 28 17:24 10

Explication

for f in [0-9]*.[a-z]*; do tmp=`echo $f | \
awk -F. '{printf "%04d.%s\n", $1, $2}'`; mv "$f" "$tmp"; done;
  • remarque les backticks: `echo ... $2}\` (La barre oblique inverse \, immédiatement au-dessus de juste divisions one-liner, sur deux lignes, pour des raisons de lisibilité)
  • dans une boucle de trouver les fichiers qui sont nommés comme des nombres avec des lettres minuscules extensions: [0-9]*.[a-z]*
  • l'écho de ce nom ($f) afin de le transmettre à awk
  • -F. : awk séparateur de champ, une période (.):s'ils correspondent, sépare les noms de fichiers sous forme de deux champs ($1 = nombre; $2 = extension)
  • format avec printf:imprimer premier champ ($1, le numéro de la partie) que 4 chiffres (%04d), puis imprimez la période, puis imprimez-le deuxième champ ($2:l'extension) comme une chaîne de caractères (%s).Tout cela est attribué à la $tmp variable
  • enfin, déplacez le fichier source ($f) pour le nouveau nom de fichier ($tmp)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top