Renaming files in a folder to sequential numbers

2019-01-03 11:50发布

I want to rename the files in a directory to sequential numbers. Based on creation date of the files.

For Example sadf.jpg to 0001.jpg, wrjr3.jpg to 0002.jpg and so on, the number of leading zeroes depending on the total amount of files (no need for extra zeroes if not needed).

24条回答
ゆ 、 Hurt°
2楼-- · 2019-01-03 12:01

The majority of the other solutions will overwrite existing files already named as a number. This is particularly a problem if running the script, adding more files, and then running the script again.

This script renames existing numerical files first:

#!/usr/bin/perl

use strict;
use warnings;

use File::Temp qw/tempfile/;

my $dir = $ARGV[0]
    or die "Please specify directory as first argument";

opendir(my $dh, $dir) or die "can't opendir $dir: $!";

# First rename any files that are already numeric
while (my @files = grep { /^[0-9]+(\..*)?$/ } readdir($dh))
{
    for my $old (@files) {
        my $ext = $old =~ /(\.[^.]+)$/ ? $1 : '';
        my ($fh, $new) = tempfile(DIR => $dir, SUFFIX => $ext);
        close $fh;
        rename "$dir/$old", $new;
    }
}

rewinddir $dh;
my $i;
while (my $file = readdir($dh))
{
    next if $file =~ /\A\.\.?\z/;
    my $ext = $file =~ /(\.[^.]+)$/ ? $1 : '';
    rename "$dir/$file", sprintf("%s/%04d%s", $dir, ++$i, $ext); 
}
查看更多
一纸荒年 Trace。
3楼-- · 2019-01-03 12:03

with "rename" command

rename -N 0001 -X 's/.*/$N/' *.jpg

or

rename -N 0001 's/.*/$N.jpg/' *.jpg
查看更多
We Are One
4楼-- · 2019-01-03 12:03

Sorted by time, limited to jpg, leading zeroes and a basename (in case you likely want one):

ls -t *.jpg | cat -n |                                           \
while read n f; do mv "$f" "$(printf thumb_%04d.jpg $n)"; done

(all on one line, without the \)

查看更多
地球回转人心会变
5楼-- · 2019-01-03 12:05

Try to use a loop, let, and printf for the padding:

a=1
for i in *.jpg; do
  new=$(printf "%04d.jpg" "$a") #04 pad to length of 4
  mv -i -- "$i" "$new"
  let a=a+1
done

using the -i flag prevents automatically overwriting existing files.

查看更多
我只想做你的唯一
6楼-- · 2019-01-03 12:06

I like gauteh's solution for its simplicity, but it has an important drawback. When running on thousands of files, you can get "argument list too long" message (more on this), and second, the script can get really slow. In my case, running it on roughly 36.000 files, script moved approx. one item per second! I'm not really sure why this happens, but the rule I got from colleagues was "find is your friend".

find -name '*.jpg' | # find jpegs
gawk 'BEGIN{ a=1 }{ printf "mv %s %04d.jpg\n", $0, a++ }' | # build mv command
bash # run that command

To count items and build command, gawk was used. Note the main difference, though. By default find searches for files in current directory and its subdirectories, so be sure to limit the search on current directory only, if necessary (use man find to see how).

查看更多
Explosion°爆炸
7楼-- · 2019-01-03 12:06

using Pero's solution on OSX required some modification. I used:

find . -name '*.jpg' \
| awk 'BEGIN{ a=0 }{ printf "mv \"%s\" %04d.jpg\n", $0, a++ }' \
| bash

note: the backslashes are there for line continuation

edit July 20, 2015: incorporated @klaustopher's feedback to quote the \"%s\" argument of the mv command in order to support filenames with spaces.

查看更多
登录 后发表回答