How to batch renumber files in a folder? (Solved)

For discussions about programming, programming questions/advice, and projects that don't really have anything to do with Puppy.
Post Reply
Message
Author
User avatar
Flash
Official Dog Handler
Posts: 13071
Joined: Wed 04 May 2005, 16:04
Location: Arizona USA

How to batch renumber files in a folder? (Solved)

#1 Post by Flash »

If this seems out of place in Programming, I'll move it to Users.

What I want to do is number all the files in a folder, in numerical order. They are already numbered, but not so I can tell where I am in their sequence.

Is there a Regular Expression I can put in ROX's Bulk rename window that will rename the files in this folder, starting with 001 for the first file (now 0101) and ending at 231 for the last file (now 1220)?
Attachments
ROX batch rename 1.jpg
(59.63 KiB) Downloaded 2087 times
ROX batch rename 2.png
(27.77 KiB) Downloaded 2192 times
Last edited by Flash on Thu 13 May 2010, 19:59, edited 2 times in total.

User avatar
MU
Posts: 13649
Joined: Wed 24 Aug 2005, 16:52
Location: Karlsruhe, Germany
Contact:

#2 Post by MU »

Hi Flash,

I don't know how to do it in rox, but this script should work.

It does not rename, but copy them.
You must set sourcefolder and targetfolder to existing directories.

Code: Select all

#!/bin/bash

sourcefolder=/root/test
targetfolder=/root/test2

c=1
ls "$sourcefolder" | while read a;do

  b=`echo "00$c" | sed "s/.*\(...\)$/\1/"`
  echo "$b.mp3"

  cp -ax "$sourcefolder/$a" "$targetfolder/$b.mp3"

  c=$(($c+1))
done
And this would rename:

Code: Select all

#!/bin/bash

sourcefolder=/root/test

c=1
ls "$sourcefolder" | while read a;do

  b=`echo "00$c" | sed "s/.*\(...\)$/\1/"`
  echo "$b.mp3"

  mv "$sourcefolder/$a" "$sourcefolder/$b.mp3"

  c=$(($c+1))
done
Please try it with a testfolder first, this is not well tested!
Note, that the suffix "mp3" is hardcoded, and not taken from the original file.

Mark
[url=http://murga-linux.com/puppy/viewtopic.php?p=173456#173456]my recommended links[/url]

User avatar
Flash
Official Dog Handler
Posts: 13071
Joined: Wed 04 May 2005, 16:04
Location: Arizona USA

#3 Post by Flash »

Thanks very much, Mark. I'll give it a try sometime in the next few days.

I assume the reason for copying the files to another folder before renaming them is in case the renaming operation doesn't work. :lol:

I should have mentioned that the 231 files in that folder amount to some 203 MB. I have 4GB of RAM, so that shouldn't be a problem; I just thought you might want to know.

User avatar
Flash
Official Dog Handler
Posts: 13071
Joined: Wed 04 May 2005, 16:04
Location: Arizona USA

#4 Post by Flash »

Mark, your script to renumber files worked perfectly. :D

Because I don't use the command line much, I'm afraid of making mistakes. To minimize that possibility, I copied the directory containing the 231 mp3 files to /tmp by dragging it in ROX. Then I opened the directory, right-clicked in the ROX window and chose Window -> Terminal Here, to open a terminal in the directory containing the mp3 files. From the forum window above, I selected your script for renaming the mp3 files and pasted it into the terminal window I had opened (I pasted it into the terminal window by clicking the right- and left- click mouse buttons at the same time.)

After I changed the script to reflect the new location of the source folder and removed the spaces from the folder names, it worked!

Thanks again. :!:

User avatar
Flash
Official Dog Handler
Posts: 13071
Joined: Wed 04 May 2005, 16:04
Location: Arizona USA

#5 Post by Flash »

Mark, I've used your renaming script many times now to renumber mp3 files in folders on a flash memory stick, without first copying the files to another folder. I even figured out how to make it start numbering from a number other than 1 (change the 1 in c=1 to whatever number you want it to start at.) I don't know what would happen if I used it to renumber the mp3 files in a directory that contained more than 999 files. :lol: I doubt I'll ever run into that problem.

To save time and eliminate the possibility of a typing error (and so I don't have to remove the spaces from directory names so the script will work,) I'd like to be able to just open a console window in the directory containing the mp3 files I want to rename, paste the script in the window and hit Enter without having to type anything. In other words, the sourcefolder would be pwd. I've tinkered around with modifying the script to do that, but without success. Any suggestions?

seaside
Posts: 934
Joined: Thu 12 Apr 2007, 00:19

#6 Post by seaside »

Flash wrote: I'd like to be able to just open a console window in the directory containing the mp3 files I want to rename, paste the script in the window and hit Enter without having to type anything. In other words, the sourcefolder would be pwd. I've tinkered around with modifying the script to do that, but without success. Any suggestions?
Flash,

This should work- change as below

Code: Select all

#!/bin/bash

#sourcefolder=/root/test 
sourcefolder=`pwd` 
Untested, so please test first.

Regards,
s

Bruce B

#7 Post by Bruce B »

I have various scripts for batch renaming files.

If I want numbers as part or all of he file name, I'll pad the numbers
for field size.

NOT

1
10
100

RATHER

001
010
100

More importantly, my various scripts do not clobber existing
files.

Suppose you have two files, one called a.txt and one called b.txt.
Then mv a.txt b.txt, you will now longer have
two files because you clobbered b.txt

My work around to make sure no .mp3 files get clobbered is only
process the .mp3 files and make them numerical only, meaning
no extensions, during the numbering and padding phase of the script.

Suppose the padding is 3 numbers (000-999), the command to run
after all the mp3 files have been numbered or renumbered could be:

a loop to mv all ??? files to add an mp3 extension.

~

User avatar
Flash
Official Dog Handler
Posts: 13071
Joined: Wed 04 May 2005, 16:04
Location: Arizona USA

#8 Post by Flash »

Thank you, seaside, it works perfectly. I didn't know to put ` around pwd.

Now all I have to do to renumber the mp3 files in a directory is open a console in the directory, paste this in the window:

Code: Select all

#!/bin/bash

sourcefolder=`pwd`

c=1
ls "$sourcefolder" | while read a;do

  b=`echo "00$c" | sed "s/.*\(...\)$/\1/"`
  echo "$b.mp3"

  mv "$sourcefolder/$a" "$sourcefolder/$b.mp3"

  c=$(($c+1))
done
and hit Enter. :D

Bruce B, perhaps I'd use your approach if I needed to renumber files that weren't mp3. Since mp3 files are the only kind I've ever needed to renumber, and I have no experience writing even simple Bash programs, MU's script works fine for me. :)

potong
Posts: 88
Joined: Fri 06 Mar 2009, 04:01

#9 Post by potong »

Batch renumbering is a good case for using the command line.

Making the command line extensible is easy too.

Here's a terminal session and an alternative solution:

Code: Select all

# # lets make some test files 
# # BTW to comment a line type M-# (thats hold down Alt and # at the same time)
# mkdir /tmp/mp3_test # make a test directory to hold test files
# # change to the test directory           
# cd /tmp/mp3_test # just type cd then type M-. to get last argument from mkdir
# pwd   
/tmp/mp3_test
# seq -w 0 20 100|xargs -n 1 -i echo touch {}.mp3 # use seq, xargs and touch  
touch 000.mp3
touch 020.mp3
touch 040.mp3
touch 060.mp3
touch 080.mp3
touch 100.mp3
# #looks OK - let's do it for real
# seq -w 0 20 100|xargs -n 1 -i touch {}.mp3 # edit out echo from previous command.
# # use C-p or up-arrow to get previous commands
# ls -l # check directory
total 0
-rw-r--r-- 1 root root 0 2010-06-18 11:56 000.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:56 020.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:56 040.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:56 060.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:56 080.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:56 100.mp3
# # lets make some test text files too
# touch {a..g}.txt # {a..g} generates a to g
# ls -l # check directory
total 0
-rw-r--r-- 1 root root 0 2010-06-18 11:56 000.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:56 020.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:56 040.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:56 060.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:56 080.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:56 100.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:59 a.txt
-rw-r--r-- 1 root root 0 2010-06-18 11:59 b.txt
-rw-r--r-- 1 root root 0 2010-06-18 11:59 c.txt
-rw-r--r-- 1 root root 0 2010-06-18 11:59 d.txt
-rw-r--r-- 1 root root 0 2010-06-18 11:59 e.txt
-rw-r--r-- 1 root root 0 2010-06-18 11:59 f.txt
-rw-r--r-- 1 root root 0 2010-06-18 11:59 g.txt
# i=0 # set a variable to zero
# # for each mp3 file we want to generate a move command
# # then we can pipe the command into bash to execute it
# # using printf rather than echo gives us more control over format
# for x in *.mp3; do printf "echo mv -v %s %04d.mp3\n" $x $((i++)); done # make our commands
echo mv -v 000.mp3 0000.mp3
echo mv -v 020.mp3 0001.mp3
echo mv -v 040.mp3 0002.mp3
echo mv -v 060.mp3 0003.mp3
echo mv -v 080.mp3 0004.mp3
echo mv -v 100.mp3 0005.mp3
# # looks good ... now we can pipe it through bash ... reset the variable first though!  
# i=0;for x in *.mp3; do printf "echo mv -v %s %04d.mp3\n" $x $((i++)); done |bash # make our commands thru bash
mv -v 000.mp3 0000.mp3
mv -v 020.mp3 0001.mp3
mv -v 040.mp3 0002.mp3
mv -v 060.mp3 0003.mp3
mv -v 080.mp3 0004.mp3
mv -v 100.mp3 0005.mp3
# # looks good ... now remove the echo command and really move the files               
# i=0;for x in *.mp3; do printf "mv -v %s %04d.mp3\n" $x $((i++)); done |bash # make our commands execute for real
`000.mp3' -> `0000.mp3'
`020.mp3' -> `0001.mp3'
`040.mp3' -> `0002.mp3'
`060.mp3' -> `0003.mp3'
`080.mp3' -> `0004.mp3'
`100.mp3' -> `0005.mp3'
# ls -l # check directory                                                                                     total 0
-rw-r--r-- 1 root root 0 2010-06-18 11:56 0000.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:56 0001.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:56 0002.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:56 0003.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:56 0004.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:56 0005.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:59 a.txt
-rw-r--r-- 1 root root 0 2010-06-18 11:59 b.txt
-rw-r--r-- 1 root root 0 2010-06-18 11:59 c.txt
-rw-r--r-- 1 root root 0 2010-06-18 11:59 d.txt
-rw-r--r-- 1 root root 0 2010-06-18 11:59 e.txt
-rw-r--r-- 1 root root 0 2010-06-18 11:59 f.txt
-rw-r--r-- 1 root root 0 2010-06-18 11:59 g.txt
# # OK let's make it into a function
# mp3renumber () { local i x;i=${1:-0};for x in *.mp3; do printf "${2:+echo} mv -v %s %04d.mp3\n" $x $((i++)); done |bash; }                          
# # make i and x into private variables ... so we don't stomp on things
# # add two parameters to the function. A <from number> and an <echo> (for testing)
# # OK let's test it out
# mp3renumber 100 a # parameter 2 can be anything it gets replaced by echo
mv -v 0000.mp3 0100.mp3
mv -v 0001.mp3 0101.mp3
mv -v 0002.mp3 0102.mp3
mv -v 0003.mp3 0103.mp3
mv -v 0004.mp3 0104.mp3
mv -v 0005.mp3 0105.mp3
# # Looks good - let's do it for real!
# mp3renumber 100  
`0000.mp3' -> `0100.mp3'
`0001.mp3' -> `0101.mp3'
`0002.mp3' -> `0102.mp3'
`0003.mp3' -> `0103.mp3'
`0004.mp3' -> `0104.mp3'
`0005.mp3' -> `0105.mp3'
# ls -l # check directory
total 0
-rw-r--r-- 1 root root 0 2010-06-18 11:56 0100.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:56 0101.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:56 0102.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:56 0103.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:56 0104.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:56 0105.mp3
-rw-r--r-- 1 root root 0 2010-06-18 11:59 a.txt
-rw-r--r-- 1 root root 0 2010-06-18 11:59 b.txt
-rw-r--r-- 1 root root 0 2010-06-18 11:59 c.txt
-rw-r--r-- 1 root root 0 2010-06-18 11:59 d.txt
-rw-r--r-- 1 root root 0 2010-06-18 11:59 e.txt
-rw-r--r-- 1 root root 0 2010-06-18 11:59 f.txt
-rw-r--r-- 1 root root 0 2010-06-18 11:59 g.txt
# # OK let's add the function to our .bashrc file 
# echo 'mp3renumber () { local i x;i=${1:-0};for x in *.mp3; do printf "${2:+echo} mv -v %s %04d.mp3\n" $x $((i++)); done |bash; }' >>~/.bashrc
# # Now we can use mp3renumber from a terminal window opened in ROX     
# # Using ROX, navigate to the mp3 directory and then press ' (on my keyboard its left of 1)
# # This opens up a terminal in the mp3 directory for you - now type mp3renumber and Bobs your Uncle
HTH

Potong

User avatar
Flash
Official Dog Handler
Posts: 13071
Joined: Wed 04 May 2005, 16:04
Location: Arizona USA

#10 Post by Flash »

Thanks for the tutorial, Potong. Mosts immediately useful to me was the tip about opening a console window in the pwd by pressing the ` key. I had no idea. :D

big_bass
Posts: 1740
Joined: Mon 13 Aug 2007, 12:21

#11 Post by big_bass »

Flash
Is there a Regular Expression I can put in ROX's Bulk rename window that will rename the files in this folder,
rox takes strings which could be a number and rename them
but you want to incrementally rename numbers and rox
wont do that



starting with 001 for the first file (now 0101) and ending at 231 for the last file (now 1220)?
since you already have a working solution
this is another way to test stuff so that you dont destroy "real files" while doing tests

you can generate "fake ones" in a different folder first

so nothing you do will ever bork your originals
now inside this folder you can test away different renaming
tricks they are all empty files
to save the space of copying all those real files


you can select any start number

Joe


*this will give you the 231 files with numbers starting with 101
to simulate the real files that need to be later renamed
===========only generate fake files =================

Code: Select all

#!/bin/bash

#fake file generator  

mkdir -p /root/mp3_fake
cd /root/mp3_fake

START_NUMBER=101
NUM=0

while [ $NUM -le 230 ]; do
    echo "fake file --> $NUM"
    touch /root/mp3_fake/$START_NUMBER.mp3
    let NUM=$NUM+1
    let START_NUMBER=$START_NUMBER+1  
done



*this will auto renumber any number of files in the folder starting with 1
of course with an easy edit you could start at any number you wish


============renumber them updated 6-19=============

Code: Select all

#!/bin/bash

#fake file renumber

mkdir -p /root/mp3_fake
cd /root/mp3_fake
START_NUMBER=1

NUM=0
ls -1 | sort -n >/root/list_mp3.txt
for i in `cat /root/list_mp3.txt`
do

    echo "fake file --> $NUM"
    mv /root/mp3_fake/$i /root/mp3_fake/$START_NUMBER.mp3 
    let NUM=$NUM+1
    let START_NUMBER=$START_NUMBER+1 
done 
rm -f /root/list_mp3.txt

User avatar
technosaurus
Posts: 4853
Joined: Mon 19 May 2008, 01:24
Location: Blue Springs, MO
Contact:

#12 Post by technosaurus »

Not at a bash terminal, but here is an untested one liner version:

Code: Select all

i=1000 && for x in `ls -1 |sort -n |basename .mp3`; do mv $x.mp3 $i-$x.mp3; let i++; done
(I forget the --flag to remove the basename extension - so that part is broken and can be removed if the extension is the same ... not sure why ls -1 AND sort -n is needed - maybe only ls -1 is sufficient for some cases
)
simplified:

Code: Select all

i=1000 && for x in `ls -1`; do mv $x $i-$x; let i++; done
to remove original numbers

Code: Select all

i=1000 && for x in `ls -1`; do mv $x $i-`echo $x |sed "s/[0-9]//g"`3; let i++; done
(Note the 3- because it ALL numbers get removed by sed)

to be able to drag a directory - something like:

Code: Select all

i=1000 && for x in `ls -1 (dirname $1)`; do mv $x $i-$x; let i++; done
Check out my [url=https://github.com/technosaurus]github repositories[/url]. I may eventually get around to updating my [url=http://bashismal.blogspot.com]blogspot[/url].

User avatar
canbyte
Posts: 264
Joined: Sat 10 Jan 2009, 20:20
Location: Hamilton, Canada

#13 Post by canbyte »

Everyone seems to find rox bulk rename easy but me. The help popup is totally confusing. It uses the verb 'matching' but does not explain how to replace. If I hit apply, the resulting message is quite unhelpful. I hit it once too often now all icons on desktop are gone. Rox is a killer! Looks like I'll have to restart x and continue, but this should be much easier or explained properly.

That done, I now have the answer for anyone else who ends up here


to rename
pic00001.jpg to baby1.jpg
pic00002.jpg etc.

put
'^pic0000' in the first box and put 'baby' in the second box

hit 'apply' to get a preview then hit 'rename'

Note however, that the unsearched for numbers are retained so that if the baby pics started off as pic00013 the 3 would be retained (or 13 if you used pic000 in the first box.) Maybe Rox can pull up it's sox!
[color=orange]1. Dell Dimension E521, AMD Athln 64, 2 GHz 1.93GB ram,
Puppy 533 on CD, accesses flash drive only,
FFox Nightly12.0
2. Compaq P3 733Hz 375RAM
Printer: Oki C3400 > LAN [/color]

Post Reply