Reputation: 1312
I have a lot of files to rename. Nearly all of those files are pictures.
The Source Filenames are something like:
DSC08828.JPG => 08828.JPG
20130412_0001.JPG => 0001.JPG
0002.JPG => 0002.JPG
IMG0047.jpg => 0047.jpg
DSC08828_1.JPG => Is a duplicate should be ignored
...
DSC08828_9.JPG => Is a duplicate should be ignored
All I want to do is to get the last Number followed by the file extension in a way that is as fast as possible (as we are talking about nearly 600.000 Pictures)
So I want to get the String from the first occurence of at least two digits from the right after the dot until the first non number character. If there is only one digit from the right, the file should be ignored.
Upvotes: 0
Views: 1731
Reputation: 10324
Here's a method using a sed
which may improve performance:
ls *.{JPG,jpg} | \
sed '
/_[1-9]*\./d; # first drop any line that appears to be a duplicate
/^[0-9]*\./d; # drop any line that does not need to be renamed
s/\(.*\)/\1 \1/; # save the original filename by duplicating the pattern space
s/ .*_/ /; # remove any leading characters followed by and including _ in the new filename
s/ [A-Z]*/ /; # remove any leading capital letters from the new filename
s/^/mv -i /; # finally insert mv command at the beginning of the line
'
When you're satisfied with the commands, feed to sh
.
Input:
0002.JPG
20130412_0001.JPG
DSC08828.JPG
DSC08828_1.JPG
DSC08828_9.JPG
IMG0047.jpg
Output:
mv -i 20130412_0001.JPG 0001.JPG
mv -i DSC08828.JPG 08828.JPG
mv -i IMG0047.jpg 0047.jpg
Upvotes: 1
Reputation: 715
sed -nr 's%^.*[^0-9]([0-9]{2,}\.[^.]+)$%\1%p' < <(find ./ -type f -iname '*.JPG')
SED dramatically faster than BASH in regexp processing, so use it instead of =~ whenever possible.
Upvotes: 1
Reputation: 14851
for x in ./*.JPG ./*.jpg; do
y=$(echo "$x"|sed '/[^0-9]//g');
echo "$x" "$y";
done
While I'm not giving you the final answer on the plate, this should get you started and illustrate the technique how to approach the tasks you described.
Depending on what you want to do with the files afterwards, you could also combine find
and grep
, such as find . -type f | grep -v '_[0-9]\.'
to filter all files containing _
followed by one digit, followed by one dot (not tested, escaping might be necessary). -v
is used to negate the matches filtered by grep
.
Since in your post you told you want to rename filter AND provided an example where you filter some files, I'm guessing you'll need both: first, filter the files you don't want, and then rename the filtered ones in a for
loop.
Upvotes: 1