Since your question is tagged Linux, you could use rename
or prename
command (note that prename
is not deprecated, though, but still works). In either case they're perl script for pattern-based renaming.
With group matching and using *.mp3
glob to pass only .mp3
files, you can do this:
$ prename -nv 's/(^0*)(.*).mp3/$2.mp3/' *.mp3
Deprecated program in use: rename as shipped with the Debian perl package will be removed after the release of stretch. Please install the separate 'rename' package which will provide the same command.
000004500.mp3 renamed as 4500.mp3
00123.mp3 renamed as 123.mp3
00133.mp3 renamed as 133.mp3
00150.mp3 renamed as 150.mp3
Note that -n
and -v
are for dry run and verbose output; testing only. Remove -n
for actual renaming to take effect.
In case you are confused about rename
vs prename
, you can read the corresponding answer that clears up the confusion, but...I would recommend that you just don't bother with that. Too convoluted :) The point is that in either case it works as shown, unless you're using ksh
shell.
Recursive way to rename files in subfolders would be via find
, however that requires a bit of acrobatics with substitution pattern to handle preceding items in the file path as provided by find
.
find ./testdir/ -type f -name "*.mp3" -exec prename -nv 's/(.*)(\/0*)(.*).mp3/$1\/$3.mp3/' {} \;
The above command performed as follows in a test case:
$ find ./testdir/ -type f -name "*.mp3" -exec prename -nv 's/(.*)(\/0*)(.*).mp3/$1\/$3.mp3/' {} \; 2>/dev/null
./testdir/000004500.mp3 renamed as ./testdir/4500.mp3
./testdir/00150.mp3 renamed as ./testdir/150.mp3
./testdir/00133.mp3 renamed as ./testdir/133.mp3
./testdir/00123.mp3 renamed as ./testdir/123.mp3
Minor improvement could be to specify \d
, the digit class:
find ./testdir/ -type f -name "*.mp3" -exec prename -nv 's/\/0*(\d*\.mp3)/\/$1/' {} \;
Stéphane Chazelas mentioned in the comments possibility where /0/1.mp3
could be accidentally rename to .//1.mp3
. I've taken couple test cases; ./testdir/0/000987.mp3 renamed as ./testdir/0/987.mp3
and ./testdir/007/00123.mp3 renamed as ./testdir/007/123.mp3
were the results. I think greedy matching of 0*
does the trick.
He also suggested in the comments adding [^/]
in filename pattern matching. This is a good idea since Unix filenames cannot have backslashes in them; paths can but not individual files. However, I am not quite sure how to better implement this and still have no suggestion on matching 0.mp3
or 000.mp3
types of filenames.
extglob
enabled supports"${file##+(0)}"
to remove a leading sequence of one or more 0s I think – steeldriver Feb 07 '18 at 21:17**
. – brhfl Feb 07 '18 at 21:24