Visit Jeremy's Blog.
Go Back > Forums > Linux Forums > Linux - Newbie
User Name
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!


  Search this Thread
Old 07-31-2006, 09:56 PM   #1
Registered: Sep 2005
Posts: 201

Rep: Reputation: 30
Help writing script

Hey friends,

I want to write a script that will descend through a parent directories subdirectories and move each specified file to another directory. I have .mp3 files gallore but they are mixed into different directories and it would be annoying to have to go through them one by one... So that's why I need this script... anyone?
Old 07-31-2006, 10:08 PM   #2
Senior Member
Registered: May 2004
Location: Albuquerque, NM USA
Distribution: Debian-Lenny/Sid 32/64 Desktop: Generic AMD64-EVGA 680i Laptop: Generic Intel SIS-AC97
Posts: 4,250

Rep: Reputation: 62
I've gotten help on that sort of things a number of times. Just today, I' linked them all to this thread

Not exactly what you're looking for, but it might get you started.
Old 07-31-2006, 11:15 PM   #3
Registered: Jul 2003
Distribution: Slackware
Posts: 390

Rep: Reputation: 53
How about:

find -xdev -iname '*mp3' -exec mv {} /home/you/some/dir \;

Old 08-01-2006, 05:20 AM   #4
Registered: Nov 2003
Location: Ireland
Distribution: Debian testing
Posts: 79

Rep: Reputation: 15
It's a very simple application of -exec but it's best not to use it.
Piping find's output to xargs gets the same job done in a more efficient and safer way. (Though not much of each of those in this situation - I'm being a bit of a facist here ;-) )


find -xdev -iname '*.mp3' | xargs -r -i mv '{}' /path/to/directory/
Old 08-01-2006, 11:50 AM   #5
LQ Newbie
Registered: May 2006
Location: Clearwater, FL
Distribution: Fedora Core 5
Posts: 2

Rep: Reputation: 0
Exclamation CAUTION -- mv is a clobberer!

Each of the other find commands posted so far has a problem! OK, its actually the mv command that has a problem...

Many Linux users are used to the -i option to mv always being there because of an alias many distributions (notably RedHat) put in the .bashrc file ... but when used in find as has been shown here, the -i option will not be aliased in... as a result, duplicated filenames will be lost, with only the last "found" file remaining.

The mv -i option prevents "clobbering" like-named files by interactively prompting you to confirm any overwrite. Being an "old-timer," I get annoyed by the -i (especially on cp)and comment out all of the aliases in my .bashrc -- but that's because I'm an old-timer!

Maybe this would be no loss for music files (because you're not likely to keep them all named music.mp3 or anything), but if there are other files (backup.tgz or something) then you'll clobber them! (I know that both my Eric Claption "Layla.mp3" files are really very different! -- One is the original, the other is "unplugged" & I'd hate to lose either one!)

I'm not so sure about the benefit (at least in this instance) of xargs over -exec -- but in either case above, the -i option added to the mv command might very well prevent the loss of some valuable music!

For any newbies, this results in the command:

find ~ -xdev -iname '*mp3' -exec mv -i '{}' /home/you/some/dir \;
NOTE: I also added a place for find to look (other than CWD): the ~ is your home directory. And I placed quotes around the {} in mv just in case there are spaces or other wierdnesses in my file/directory names.

Peace, Love, and Unix!
Old 08-01-2006, 12:12 PM   #6
Registered: Nov 2003
Location: Ireland
Distribution: Debian testing
Posts: 79

Rep: Reputation: 15
Yes, very good. I've been hit by such clobbering before *shudder*
As you say, xargs is really not necessary at all but my mother told me there was something wrong with me if I didn't write with my right hand and use xargs ;-)
You could do some godawful intermediate stuff with sort and uniq but the above code works best - don't want to spend as much time debugging as it would take to do it by hand.
-p for xargs does the same as -i for mv but you'd have a list of about 100 filenames that you'd have to manually check for uniqueness... Jesus I'm rambling with poor grammar/clarity

Go with it4soho!
Old 08-01-2006, 07:08 PM   #7
LQ Newbie
Registered: Jul 2006
Posts: 2

Rep: Reputation: 0
Sometimes you actually need a script

Like many of you, I like the simple one-line solutions. But sometimes these result in scripts that are either too simple (like the one which clobbers like-named files), or too complex, or sometimes just too hard to use correctly. For instance, what if you do a "find / ...." ? You'll get lots of error messages about trying to move a file over itself.

In cases like this, you're better off not trying to write a clever one-liner. Here's a script that only took a few minutes to write....

-- It is written in ksh, but it ought to work
in bash and most modern Bourne shells as well.

-- It automatically renames the files to
file_2.mp3, file_3.mp3, etc. in the
event of a naming conflict.

-- It keeps a log of where the files came from
and what they were ultimately named.

-- It handles both mp3 and MP3 extensions. It doesn't
do mixed case extensions (i.e. .Mp3 or .mP3),
though it could.

-- It will be OK even if the target directory is
underneath the search directory (e.g. "fromTree=/")

# Quick script to move all MP3s on a system to a single directory.


echo >> $logFile
echo ========== `date` =========== >> $logFile

find $fromTree \( -name "*.mp3" -o -name "*.MP3" \) -print | while true; do
read mp3File || break

## Remove .mp3 and .MP3 extensions
## This is inefficient, but it's good enough for quick-and-dirty script
base=`basename $mp3File .mp3`
base=`basename $base .MP3`

## Where shall we put the file

## Make sure we are not moving the file over itself!
[ $target = $mp3File ] && continue

## If there is a name conflict, append a number
while [ -f $target ]; do #
## Use "expr" since some shells don't have $(( ))
cnt=`expr $cnt + 1`

echo "$mp3File $target" >> $logFile # There's a <TAB> in that echo
mv $mp3File $target

done ## end of "find | while true; read.... "
Old 08-01-2006, 08:43 PM   #8
LQ Newbie
Registered: Apr 2005
Posts: 6
Blog Entries: 1

Rep: Reputation: 0
find -exec vs. find |xargs

what's the difference of this two in terms of efficiency and safety?
Old 08-02-2006, 06:59 AM   #9
Registered: Jul 2003
Distribution: Slackware
Posts: 390

Rep: Reputation: 53
I had no idea my post would create so much controversy. That's great, I learned something. I guess I thought the filenames would all be different.

Old 08-02-2006, 10:45 PM   #10
Registered: Sep 2005
Posts: 201

Original Poster
Rep: Reputation: 30
I'd just like to thank you all for your valuable input and confirm that it worked like a charm.


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
Help writing with SH script? SirJinX Programming 1 01-24-2006 06:57 AM
Help writing a script mral Linux - Newbie 4 12-29-2005 01:34 AM
help with writing a script jedimastermopar Linux - General 10 05-02-2005 02:34 PM
Writing a Script Nyc0n Linux - General 2 05-27-2002 08:21 PM
writing a Script spanky5125 Linux - Security 5 01-08-2002 10:22 AM > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 08:35 PM.

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