J'ai un tas de fichiers nommés comme suit:
output_1.png
output_2.png
...
output_10.png
...
output_120.png
Quel est le moyen le plus simple de renommer ceux qui correspondent à une convention, par exemple avec un maximum de quatre décimales pour que les fichiers soient nommés:
output_0001.png
output_0002.png
...
output_0010.png
output_0120.png
Cela devrait être facile sous Unix/Linux/BSD, même si j'ai également accès à Windows. Toutes les langues sont acceptables, mais je suis intéressé par des one-liners vraiment bien (s'il y en a?).
import os
path = '/path/to/files/'
for filename in os.listdir(path):
prefix, num = filename[:-4].split('_')
num = num.zfill(4)
new_filename = prefix + "_" + num + ".png"
os.rename(os.path.join(path, filename), os.path.join(path, new_filename))
vous pouvez compiler une liste de noms de fichiers valides en supposant que tous les fichiers commençant par "output_" et finissant par ".png" sont des fichiers valides:
l = [(x, "output" + x[7:-4].zfill(4) + ".png") for x in os.listdir(path) if x.startswith("output_") and x.endswith(".png")]
for oldname, newname in l:
os.rename(os.path.join(path,oldname), os.path.join(path,newname))
(de: http://www.walkingrandomly.com/?p=2850 )
En d'autres termes, je remplace fichier1.png par fichier001.png et fichier20.png par fichier020.png, etc. Voici comment faire cela en bash
#!/bin/bash
num=`expr match "$1" '[^0-9]*\([0-9]\+\).*'`
paddednum=`printf "%03d" $num`
echo ${1/$num/$paddednum}
Enregistrez ce qui précède dans un fichier appelé zeropad.sh
, puis exécutez la commande suivante pour le rendre exécutable.
chmod +x ./zeropad.sh
Vous pouvez ensuite utiliser le script zeropad.sh
comme suit
./zeropad.sh frame1.png
qui retournera le résultat
frame001.png
Il ne reste plus qu'à utiliser ce script pour renommer tous les fichiers .png du répertoire en cours de manière à ce qu'ils soient zéros ajoutés.
for i in *.png;do mv $i `./zeropad.sh $i`; done
(from: Renommer le pavé zéro, par exemple Image (2) .jpg -> Image (002) .jpg )
use strict;
use warnings;
use File::Find;
sub pad_left {
my $num = shift;
if ($num < 10) {
$num = "00$num";
}
elsif ($num < 100) {
$num = "0$num";
}
return $num;
}
sub new_name {
if (/\.jpg$/) {
my $name = $File::Find::name;
my $new_name;
($new_name = $name) =~ s/^(.+\/[\w ]+\()(\d+)\)/$1 . &pad_left($2) .')'/e;
rename($name, $new_name);
print "$name --> $new_name\n";
}
}
chomp(my $localdir = `pwd`);# invoke the script in the parent-directory of the
# image-containing sub-directories
find(\&new_name, $localdir);
Aussi de la réponse ci-dessus:
rename 's/\d+/sprintf("%04d",$&)/e' *.png
Assez facile, bien qu'il combine quelques fonctionnalités qui ne sont pas immédiatement évidentes:
@echo off
setlocal enableextensions enabledelayedexpansion
rem iterate over all PNG files:
for %%f in (*.png) do (
rem store file name without extension
set FileName=%%~nf
rem strip the "output_"
set FileName=!FileName:output_=!
rem Add leading zeroes:
set FileName=000!FileName!
rem Trim to only four digits, from the end
set FileName=!FileName:~-4!
rem Add "output_" and extension again
set FileName=output_!FileName!%%~xf
rem Rename the file
rename "%%f" "!FileName!"
)
Edit: indiquez que vous ne recherchez pas un fichier de commandes, mais une solution dans n'importe quelle langue. Désolé. Pour compenser cela, un PowerShell one-liner:
gci *.png|%{rni $_ ('output_{0:0000}.png' -f +($_.basename-split'_')[1])}
Collez un ?{$_.basename-match'_\d+'}
à cet endroit si d'autres fichiers ne suivent pas ce modèle.
En fait, je devais juste le faire sous OSX. Voici les scripts que j'ai créés pour cela - une seule ligne!
> for i in output_*.png;do mv $i `printf output_%04d.png $(echo $i | sed 's/[^0-9]*//g')`; done
Here est un script Python que j'ai écrit et qui compile les zéros en fonction du plus grand nombre présent et ignore les fichiers non numérotés du répertoire donné. Usage:
python ensure_zero_padding_in_numbering_of_files.py /path/to/directory
Corps du script:
import argparse
import os
import re
import sys
def main(cmdline):
parser = argparse.ArgumentParser(
description='Ensure zero padding in numbering of files.')
parser.add_argument('path', type=str,
help='path to the directory containing the files')
args = parser.parse_args()
path = args.path
numbered = re.compile(r'(.*?)(\d+)\.(.*)')
numbered_fnames = [fname for fname in os.listdir(path)
if numbered.search(fname)]
max_digits = max(len(numbered.search(fname).group(2))
for fname in numbered_fnames)
for fname in numbered_fnames:
_, prefix, num, ext, _ = numbered.split(fname, maxsplit=1)
num = num.zfill(max_digits)
new_fname = "{}{}.{}".format(prefix, num, ext)
if fname != new_fname:
os.rename(os.path.join(path, fname), os.path.join(path, new_fname))
print "Renamed {} to {}".format(fname, new_fname)
else:
print "{} seems fine".format(fname)
if __== "__main__":
sys.exit(main(sys.argv[1:]))
Pour renommer en masse le seul safe solution est mmv
-, il vérifie les collisions et permet de renommer des chaînes et des cycles, ce qui dépasse la plupart des scripts. Malheureusement, zéro padding n'est pas trop chaud. Une saveur:
c:> mmv output_[0-9].png output_000#1.png
Voici une solution de contournement:
c:> type file
mmv
[^0-9][0-9] #1\00#2
[^0-9][0-9][^0-9] #1\00#2#3
[^0-9][0-9][0-9] #1\0#2#3
[^0-9][0-9][0-9][^0-9] #1\0#2#3
c:> mmv <file
$rename output_ output_0 output_? # adding 1 zero to names ended in 1 digit
$rename output_ output_0 output_?? # adding 1 zero to names ended in 2 digits
$rename output_ output_0 output_??? # adding 1 zero to names ended in 3 digits
C'est tout!
Je suis la solution d'Adam pour OSX.
Voici quelques gotchyas rencontrés dans mon scénario:
Au final, ma ligne de conversion ressemblait à ceci:
for i in *.mp3 ; do mv "$i" `printf "track_%02d.mp3\n" $(basename "$i" .mp3 | sed 's/[^0-9]*//g')` ; done