LinuxQuestions.org
Help answer threads with 0 replies.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-19-2006, 03:56 PM   #1
FreeDoughnut
Member
 
Registered: Jun 2006
Distribution: Slackware 10.2, Debian Testing/Unstable, Ubuntu Breezy Badger, working on LFS
Posts: 228

Rep: Reputation: 30
Bash Renaming (removing a string from filenames)


I switched CD ripping programs recently, and the first one didn't organize my music in folders. The new one does, so I did it manually. What I have now is:
Quote:
/mnt/music/music/Pink Floyd/Dark Side Of The Moon/Pink Floyd - Eclipse.ogg #OLD
/mnt/music/music/Rush/Moving Pictures/Tom Sawyer.ogg #NEW
So I'm working on a bash command to change the old ones to be like the new ones. What I have so far from my Googling is:
Quote:
for i in `ls`; do mv $i `echo $i | sed ' s/Pink\ Floyd\ -\ /\ /' `; done
But due to some discrepency between sed and mv and the for loop, mv processes each space seperated part as a seperate file, so I get errors like:
Quote:
mv: invalid option -- \
Try `mv -help' for more information.
mv: cannot stat `Us\\': No such file or directory
mv: cannot stat `And\\': No such file or directory
mv: cannot stat `Them.ogg': No such file or directory
However,
Quote:
mv "Pink Floyd - Money.ogg" `echo "Pink Floyd - Money.ogg" | sed ' s/Pink\ Floyd\ -\ //' `
gives me "Money.ogg". How do I coordinate every program's way of processing "\ "s and " "s so that I can make my music collection consistent?

Thanks for any help, and I'm a newbie to bash scripting, so please explain any changes to my original command.
 
Old 07-19-2006, 04:05 PM   #2
FreeDoughnut
Member
 
Registered: Jun 2006
Distribution: Slackware 10.2, Debian Testing/Unstable, Ubuntu Breezy Badger, working on LFS
Posts: 228

Original Poster
Rep: Reputation: 30
D'oh! I feel like hitting myself. I always figure my questions out right after posting.
I ended up replacing "for i in `ls`" with "for i in *"
So for any other Bash newbies out there, my final command is:
Quote:
for i in *; do mv "$i" "`echo "$i" | sed ' s/Pink\ Floyd\ -\ //' `"; done
 
Old 07-19-2006, 05:06 PM   #3
taylor_venable
Member
 
Registered: Jun 2005
Location: Indiana, USA
Distribution: OpenBSD, Ubuntu
Posts: 892

Rep: Reputation: 43
Actually, I think it was putting the double quotes around $i and your sed command (the parameters to the mv program) that fixed it...

And for safety's sake (because you have, I believe, incorrectly nested quotes) you might want to remove the double quotes around the $i parameter to the echo command. In other words, I would try:

Code:
for i in `ls -1`; do mv "$i" "`echo $i | sed ' s/Pink\ Floyd\ -\ //' `"; done
It may work now, which is good, but I think these fixes may make it more stable.

Last edited by taylor_venable; 07-19-2006 at 05:08 PM.
 
Old 07-19-2006, 05:43 PM   #4
spooon
Senior Member
 
Registered: Aug 2005
Posts: 1,755

Rep: Reputation: 51
A much better way of renaming files is
Code:
rename "Pink Floyd - " "" *
Quote:
Originally Posted by taylor_venable
Actually, I think it was putting the double quotes around $i and your sed command (the parameters to the mv program) that fixed it...

And for safety's sake (because you have, I believe, incorrectly nested quotes) you might want to remove the double quotes around the $i parameter to the echo command. In other words, I would try:

Code:
for i in `ls -1`; do mv "$i" "`echo $i | sed ' s/Pink\ Floyd\ -\ //' `"; done
It may work now, which is good, but I think these fixes may make it more stable.
This won't work. Because the for loop takes a list, and the list separator characters include space, the for loop will iterate through each space-separated word, and this has nothing to do with the quoting of $i. So you would either have to temporarily change the list separator characters; or use the read command:
Code:
ls -1 | while read i; do mv "$i" "`echo $i | sed ' s/Pink\ Floyd\ -\ //' `"; done
 
Old 07-19-2006, 07:35 PM   #5
FreeDoughnut
Member
 
Registered: Jun 2006
Distribution: Slackware 10.2, Debian Testing/Unstable, Ubuntu Breezy Badger, working on LFS
Posts: 228

Original Poster
Rep: Reputation: 30
Well, thanks for all your input! I figured out how to do it, and now have an easier way for in the future. This forum is great.
 
Old 07-19-2006, 10:01 PM   #6
taylor_venable
Member
 
Registered: Jun 2005
Location: Indiana, USA
Distribution: OpenBSD, Ubuntu
Posts: 892

Rep: Reputation: 43
Quote:
Originally Posted by spooon
This won't work. Because the for loop takes a list, and the list separator characters include space, the for loop will iterate through each space-separated word, and this has nothing to do with the quoting of $i.
Oh, yeah; my mistake. So when you use the star * wildcard, it must automatically escape special characters when it's expanded, right? Otherwise it would cause the same problem. Is it therefore not necessary to quote $i in this case, because the spaces and such are already escaped? (I notice you still quote it in your example, so I'm wondering.) Thanks.
 
Old 07-19-2006, 10:13 PM   #7
spooon
Senior Member
 
Registered: Aug 2005
Posts: 1,755

Rep: Reputation: 51
Quote:
Originally Posted by taylor_venable
Oh, yeah; my mistake. So when you use the star * wildcard, it must automatically escape special characters when it's expanded, right? Otherwise it would cause the same problem. Is it therefore not necessary to quote $i in this case, because the spaces and such are already escaped? (I notice you still quote it in your example, so I'm wondering.) Thanks.
In my example, I didn't use a for loop at all. I use read in a while loop to read one line at at time from the output of "ls -1".
 
Old 07-20-2006, 01:38 AM   #8
spirit receiver
Member
 
Registered: May 2006
Location: Frankfurt, Germany
Distribution: SUSE 10.2
Posts: 424

Rep: Reputation: 33
Quote:
Originally Posted by FreeDoughnut
But due to some discrepency between sed and mv and the for loop, mv processes each space seperated part as a seperate file,
That's because of the loop, the argument of the loop will be split at space characters (among others) into the separate parameters for each loop. You can change that behaviour by setting the IFS internal variable in Bash, for example IFS=$'\n' makes sure that it will only be split at newline characters.
 
Old 07-20-2006, 10:18 AM   #9
taylor_venable
Member
 
Registered: Jun 2005
Location: Indiana, USA
Distribution: OpenBSD, Ubuntu
Posts: 892

Rep: Reputation: 43
Quote:
Originally Posted by taylor_venable
So when you use the star * wildcard, it must automatically escape special characters when it's expanded, right? Otherwise it would cause the same problem. Is it therefore not necessary to quote $i in this case, because the spaces and such are already escaped?
I'll answer my own question, in case anybody is interested. No, it is necessary to quote $i even when $i is generated as an expansion of the star wildcard. Failing to quote $i in this situation will cause an error for the mv program because of the spaces embedded in the filename. And this is why putting spaces in filenames is evil.
 
Old 07-20-2006, 09:54 PM   #10
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
to FreeDoughnut:

you may also use $(...) instead of `...`. it's more stable and can be nested. remember that this is not available in sh.

on your command by the way. you might also use:

Code:
for a in *; do echo mv "$a" "${a/* - }"; done
remove the echo if you think the code is already correct
no need to use sed there

read the parameter expansion section of bash's manual. do man bash. it can really help.
 
  


Reply



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 Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Renaming array elements in bash bryan.out.there Programming 2 05-31-2006 11:44 PM
Batch Renaming in bash xushi Programming 6 07-07-2005 03:24 PM
bash help renaming files kahn Programming 6 06-16-2005 07:15 AM
Bash script renaming a variable zael Programming 3 09-30-2003 04:37 AM
renaming and moving filenames nightjar Linux - General 10 03-01-2003 09:30 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 04:49 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration