Welcome to Linux Forums!

With a comprehensive Linux Forum, information on various types of Linux software and many Linux Reviews articles, we have all the knowledge you need a click away, or accessible via our knowledgeable members.

Linux Forum ArticlesLinux ForumsLinux Forum DownloadsLinux HostsFree MagazinesJobs
Home|Register|FAQ|Member List|Calendar|Unanswered Posts|Forum Rules|Today's Posts|Advanced Search|
SEARCH FOR IN
Go Back   Linux Forums > GNU Linux Zone > Linux Programming & Scripting
Reload this Page Bulk rename using terminal
Linux Forums
Linux Forums
Welcome To The Linux Forums!
Welcome to Linux Forums. We pride ourselves in being one of the largest Linux communities on the web, we encourage you to REGISTER on our forums and participate in the community. There are over 150,000 members ready to answer your questions. JOINING US today will allow you to make new posts, get support, send messages to other members and submit downloads to our downloads directory and many other great features!

Linux Programming & Scripting C, Perl, PHP, Bash Scripts, anything programming or script related post in here!

Reply
 
Thread Tools Display Modes
Old 06-18-2008   #1 (permalink)
Just Joined!
 
Join Date: May 2006
Posts: 11
Bulk rename using terminal

I am looking for a method to bulk rename files using the terminal.
I don't want to use krename or any other application,I want to learn to do this in a terminal.

For example if I had these files named as follows,

abc-two_first.mp3
abc-two_second.mp3
abc-two_third.mp3

What would be the easiest way to rename the files to this?

first.mp3
second.mp3
third.mp3

I want to remove abc-two_ from all the filenames in a directory.

Would the rename command be best for this,or the mv command?
Or a combination of both commands put into a script?
linny is offline   Reply With Quote
Old 06-19-2008   #2 (permalink)
Linux Engineer
 
Join Date: Nov 2007
Location: Córdoba (Spain)
Posts: 1,159
Quote:
Originally Posted by linny View Post
I am looking for a method to bulk rename files using the terminal.
I don't want to use krename or any other application,I want to learn to do this in a terminal.

For example if I had these files named as follows,

abc-two_first.mp3
abc-two_second.mp3
abc-two_third.mp3

What would be the easiest way to rename the files to this?

first.mp3
second.mp3
third.mp3

I want to remove abc-two_ from all the filenames in a directory.

Would the rename command be best for this,or the mv command?
Or a combination of both commands put into a script?
Code:
for file in /path/to/*; do echo mv "$file" "${file/abc-two_/}"; done
If you like what you see, remove "echo" and the mv commands will actually be run.

I recommend you to google for "bash string mangling" to know how to handle strings in bash. Most times if it's something simple you don't need any external programs.

About the rest of the command, google for the "advanced bash scripting guide". Regardless of it's name, it's perfectly suitable for all levels, even newcomers to bash scripting.
i92guboj is offline   Reply With Quote
Old 06-20-2008   #3 (permalink)
Just Joined!
 
Join Date: May 2006
Posts: 11
Thanks i92guboj for the reply.
I did have a look at bash string mangling as you suggested.

I have found a way to do this with the rename command as well.
It's not so much that I don't want to use a script,but that I am looking for the very easiest way to accomplish this task.
As in my previous examples,this also works to remove what I asked about.
rename "abc-two_" " " *

I am quite stumped on one aspect though,expecially with the rename command.
When filenames begin with 01,02,03,04 etc,how can I remove these prefixes?

Every command I have looked into suggests that a "match",(oldname) is needed to be specified,then a (newname) specified to replace all the matches found.
01,02,03 etc are all different,not a match by themselves,and to enter all these numbers so a match can be found for all of them,it would be just as easy to right click,rename the file.

If the numbers 01,02,03 etc are all preceeded by a -,such as 01-,02- etc.,can this - be used to specify(maybe as a seperator) in the command to replace everything that is found before the - with a space?
Or better yet,just delete what it finds before the -?

Thanks again for the reply.
This is a bit over my head but I'm trying,and I can use all the help I can get.
linny is offline   Reply With Quote
Old 06-20-2008   #4 (permalink)
Linux Enthusiast
 
Freston's Avatar
 
Join Date: Mar 2007
Posts: 573
Heheh, I gave this link twice yesterday. And once today I think you will find you can manipulate strings from within bash itself quite easily.

And if you put this in a 'for' loop, like i92guboj suggested, you can rename entire directories in one command. What you'll end up with is something like this: (Untested!!!)
Code:
for FILE in /path/to/*mp3 ; do
   NEWNAME=${FILE##*_} # Strips everything to the left of the first '_'
   echo mv /path/to/$FILE /path/to/$NEWNAME # 'echo' is our safety feature
done
You could run this as one line from the command line, but that's harder to evaluate if some unexpected behavior occurs

Let us know if this is what you where looking for and if you could get it to work.
__________________
Can't tell an OS by it's GUI
Freston is offline   Reply With Quote
Old 06-20-2008   #5 (permalink)
Just Joined!
 
Join Date: May 2006
Posts: 11
I'm not doing this right or something,nothing happens.

I have a test directory on my desktop.
Inside are three more directories named
01- rename_a
02- rename_b
03- rename_c

I tried this from your example.

Code:
for File in home/username/Desktop/test/*rename ; do
> NEWNAME=${FILE##*_}
> done
What did I do wrong?
linny is offline   Reply With Quote
Old 06-20-2008   #6 (permalink)
Linux Enthusiast
 
Freston's Avatar
 
Join Date: Mar 2007
Posts: 573
Quote:
Originally Posted by linny
What did I do wrong?
I was thinking why you didn't include the error, but then it struck me. There was no error. The machine did what you asked.

But all it did was make a list of all files that /end/ in 'rename', rather than make a list of all files that /contain/ 'rename'. And then *drumroll* it sets a variable and exists. That's not very exciting is it

Try this:
Code:
for FILE in /home/username/Desktop/test/*rename* ; do
    NEWNAME=${FILE##*_}
    echo $FILE will become $NEWNAME
done
Oh... And although arbitrary, names of variables are case sensitive. $File is not the same as $FILE or $file.
Also, it seems you have spaces in your names. That matters not a lot, but remember that normally in bash a space is a separator. You might need to escape it with '\'. Probably not now though, because in this script bash will do this for you. Just keep in mind that to call a file with the name '10 blablabla' it has to be written '10\ blablabla'.

EDIT: Don't get me wrong. I'm not trying to criticize, as I'm well aware of how easy it is to miss small mistakes that make scripts function differently than you'd expect. you wrote:
for File in home/username/Desktop/test/*rename ; do
which should have been:
for FILE in /home/username/Desktop/test/*rename* ; do
__________________
Can't tell an OS by it's GUI
Freston is offline   Reply With Quote
Old 06-21-2008   #7 (permalink)
Just Joined!
 
Join Date: May 2006
Posts: 11
Quote:
I'm not trying to criticize
I didn't sense that at all.
I read every word like it's gold.
I want my mistakes pointed out to me.
I'm wanting to learn how to get this job done,and if that's what it takes,criticize away.
You call it criticize,I call it help!

I'm not sure if I only posted the mistakes you noted here,or if I actually entered them in terminal also.
So I went back and made sure those mistakes weren't present.
Still no results at all.

I tried the command as you presented it,this is the result.
Code:
$ for FILE in /home/user/Desktop/test/*rename* ; do
> NEWNAME=${FILE##*_}
> echo $FILE will become $NEWNAME
> done
/home/user/Desktop/test/01-rename_a will become a
/home/user/Desktop/test/01-test_rename_a _rename_a will become a
/home/user/Desktop/test/02-rename_b will become b
/home/user/Desktop/test/02-test_rename_b will become b
/home/user/Desktop/test/03-rename_c will become c
/home/user/Desktop/test/03-test_rename_c will become c
The results of echo show that something will be done,although not what I wanted.
I only want the 01,02,03 etc. removed.


I entered the command as follows anyway,without echo,because this is only a test directory.
Code:
for FILE in /home/user/Desktop/test/*rename* ; do
> NEWNAME=${FILE##*_}
> done
Nothing happened at all.
This is ls after I entered the above command.
ls
01-rename_a/ 02-rename_b/ 03-rename_c/
01-test_rename_a _rename_a 02-test_rename_b 03-test_rename_c
01- trip.txt 02- trip.txt 03- trip.txt


I am surely confused now.
Why did echo say things would happen,then they never did?
As the above echo states,two files will become a,two files will become b,etc,
You can't have two files in the same directory with the same name,so maybe this is why "nothing happened"?
Feel very free to criticize!
linny is offline   Reply With Quote
Old 06-21-2008   #8 (permalink)
Linux Engineer
 
Join Date: Nov 2007
Location: Córdoba (Spain)
Posts: 1,159
Quote:
Originally Posted by Freston View Post
Code:
for FILE in /path/to/*mp3 ; do
   NEWNAME=${FILE##*_} # Strips everything to the left of the first '_'
   echo mv /path/to/$FILE /path/to/$NEWNAME # 'echo' is our safety feature
done
Note that this will screw up everything if there's any strange character in the middle, this is why it's a good idea to quote filenames when you do massive operations in loops. Like this:

Code:
for FILE in /path/to/*mp3 ; do
   NEWNAME="${FILE##*_}" # Strips everything to the left of the first '_'
   echo mv "/path/to/$FILE" "/path/to/$NEWNAME" # 'echo' is our safety feature
done
It's a good habit that will save you lots of pain in the future.

If you like what you see, then remove the echo part so the mv is actually run.
i92guboj is offline   Reply With Quote
Old 06-21-2008   #9 (permalink)
Linux User
 
Join Date: Aug 2006
Posts: 353
Quote:
Originally Posted by linny View Post
I am looking for a method to bulk rename files using the terminal.
I don't want to use krename or any other application,I want to learn to do this in a terminal.

For example if I had these files named as follows,

abc-two_first.mp3
abc-two_second.mp3
abc-two_third.mp3

What would be the easiest way to rename the files to this?

first.mp3
second.mp3
third.mp3

I want to remove abc-two_ from all the filenames in a directory.

Would the rename command be best for this,or the mv command?
Or a combination of both commands put into a script?
Code:
ls abc-* | awk 'BEGIN{FS="_";q="\047"}{system( "mv "q $0 q" "q $2 q )}'
ghostdog74 is offline   Reply With Quote
Old 06-21-2008   #10 (permalink)
Linux Enthusiast
 
Freston's Avatar
 
Join Date: Mar 2007
Posts: 573
Quote:
Originally Posted by linny
Feel very free to criticize!
I shall

The problem is this:
Code:
for FILE in /home/user/Desktop/test/*rename* ; do
NEWNAME=${FILE##*_}
done
You left out the 'move' line. With 'NEWNAME=${FILE##*_}' bash just sets a new variable. But it doesn't actually do anything. (And be glad for that, as it makes setting variables that much safer )



Now to take into account this:
Quote:
Originally Posted by linny
The results of echo show that something will be done,although not what I wanted.
I only want the 01,02,03 etc. removed.
I take it you want 01-rename_a to be called rename_a. So we have to strip the name of 01-. And the same for the other files.
Then we simply tell bash to strip everything (and including) to the left of the first '-'.
Thus: "${FILE##*-}"
Also, in hindsight, there is no need for a separate NEWFILE variable. We can safely shave of an extra line from the script.


Now because this is a test directory, we'll abandon all necessary precautions and move straight to business.

cd /path/to/testdir/
sleep 3 # to feel the tension rise
Code:
for FILE in /path/to/testdir/ ; do
mv $FILE ${FILE##*-}
done
There is no way to undo this. So if used against large sets of valuable data, use the cp -i rather than mv. And have the source files in another directory as the target files. And I always use echo in front of the line that does the work on the first run, to check manually if what I want to happen is what is actually gonna happen.



Quote:
Originally Posted by i92guboj
Note that this will screw up everything if there's any strange character in the middle, this is why it's a good idea to quote filenames when you do massive operations in loops.
(...)
It's a good habit that will save you lots of pain in the future.
Solid advice! That is indeed a good habit (and one I've been neglecting)
__________________
Can't tell an OS by it's GUI
Freston is offline   Reply With Quote
Reply



Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off
 

Free Magazines
Cisco News
Receive a free quarterly e-newsletter with exclusive articles on how Cisco IT uses its own products and solutions to enable the business.
subscribe
Systems Management News, the newspaper for IT systems administration and data center managers!
Each issue of Systems Management News is chock-full of news and analysis to help you understand what's happening in your field.
subscribe
The Enterprise Newsweekly
eWeek is the essential technology information source for builders of e-business.
subscribe
Oracle Magazine
Oracle Magazine contains technology strategy articles, sample code, tips, Oracle and partner news, how to articles for developers and DBAs, and more. Oracle (NASDAQ: ORCL) is the world's largest enterprise software company.
subscribe
Total Telecom
Total Telecom is "The Economist of the communications industry".
subscribe
More free magazines »



All times are GMT. The time now is 04:40 AM.




© 2000 - 2008 - All Rights Reserved - Property of  MAS Media

Content Relevant URLs by vBSEO 3.2.0