Reputation: 19
I have a bunch of files like:
bla.super.lol.S01E03.omg.bbq.mp4
bla.super.lol.S01E04.omg.bbq.mp4
bla.super.lol.s03e12.omg.bbq.mp4
I need to rename them all like:
s01e03.mp4
s01e04.mp4
s03e12.mp4
I've tried to do it with for file in *; do mv $file ${file%%\.omg*}; done
but it removes only part after S01E01, not before it
so please, help
Upvotes: 1
Views: 118
Reputation: 3474
A pure Bash solution:
for f in *.mp4; do
IFS=. read -r _ _ _ s _ <<< "$f"
mv -- "$f" "${s,,}.mp4"
done
To test it, I created the following tree:
tree
.
├── bla.super.lol.S01E03.omg.bbq.mp4
├── bla.super.lol.S01E04.omg.bbq.mp4
└── bla.super.lol.s03e12.omg.bbq.mp4
0 directories, 3 files
Let's put a printf
before mv
to be sure about the changes:
mv -- bla.super.lol.S01E03.omg.bbq.mp4 s01e03.mp4
mv -- bla.super.lol.S01E04.omg.bbq.mp4 s01e04.mp4
mv -- bla.super.lol.s03e12.omg.bbq.mp4 s03e12.mp4
Looks good. The season part is extracted, and lower-cased as requested.
Upvotes: 1
Reputation: 2691
Many Linuxes ship a nice command line tool called rename
that eats Perl regular expressions:
rename 's/.*\.(\w+\d)\..*/$1.mp4/;y/A-Z/a-z/' *.mp4
Upvotes: 4
Reputation: 61512
Simple Perl script that tries to parse out the episode information, skips files where it can't find them.
#!perl
use strict;
use warnings;
use File::Copy qw(move);
foreach my $file ( glob('*.mp4') ) {
my ($info) = $file =~ m/([sS]\d+[eE]\d+)/;
next unless $info;
my $new_filename = lc $info . ".mp4";
move $file, $new_filename
or die "$!";
}
Upvotes: 2
Reputation: 5730
If your filenames are always dot-separated and the SExxEmm part is always the 4th one, then I'd do it with awk:
for file in *; do
mv $file $(echo $file | awk -F. '{print $4 "." $NF}');
done
awk -F.
splits the filename at the dots apart and then prints the 4th and last field.
To do a "dry run" (i.e. show the commands instead of executing them), prepend them with echo
:
for file in *; do
echo mv $file $(echo $file | awk -F. '{print $4 "." $NF}');
done
Upvotes: 0