Need to move files but not directories

Where Penguins and Daemons chill together in the warmth of the Sun.

Moderators: SecretSquirrel, notfred

Need to move files but not directories

Postposted on Mon Sep 28, 2009 11:24 pm

So, I have this nifty new program that will automatically organize my collection, at least visually not on disk.

What I need to do is move files from one directory and all of its subdirectories, but not the directories themselves. Also, I'd like to exclude the .ini files Windows may have created.

Otherwise, the only file types that are in them are FLAC or Ogg.

Would somebody provide the CLI command to accomplish such a task, please?
The best things in life are free.
http://www.gentoo.org
Guy 1: Surely, you will fold with me.
Guy 2: Alright, but don't call me Shirley.
titan
Grand Gerbil Poohbah
 
Posts: 3276
Joined: Mon Feb 18, 2002 6:00 pm
Location: Great Smoky Mountains

Re: Need to move files but not directories

Postposted on Tue Sep 29, 2009 9:22 am

Where do you want them to go? All in to a single different directory, or do you want to preserve the subdirectory layout when you move them.

I'm thinking along the lines of using "find", add a prune for "-name *.ini" and "-exec mv \{\} blah \;" but wondering if blah is enough or if you need to manipulate that as well maybe by doing a basename on the \{\}.
notfred
Grand Gerbil Poohbah
 
Posts: 3650
Joined: Tue Aug 10, 2004 9:10 am
Location: Ottawa, Canada

Re: Need to move files but not directories

Postposted on Tue Sep 29, 2009 9:48 am

...and if you need to preserve the directory layout, does that layout already exist at the destination location or does it need to be created on the fly?
(this space intentionally left blank)
just brew it!
Administrator
Gold subscriber
 
 
Posts: 36917
Joined: Tue Aug 20, 2002 9:51 pm
Location: Somewhere, having a beer

Re: Need to move files but not directories

Postposted on Tue Sep 29, 2009 9:58 am

So you're moving music? Foobar2k has a file operations function that can sort your music into directories and such.
Image
Nitrodist
Grand Gerbil Poohbah
 
Posts: 3280
Joined: Wed Jul 19, 2006 12:51 am
Location: Minnesota

Re: Need to move files but not directories

Postposted on Tue Sep 29, 2009 3:14 pm

No, I don't need to preserve directories. I'm going from multiple directories to a single directory.

The current locations of the files is:
music/genre/artist/audio_files.{flac,ogg,mp3}

And they'll all be going to:
media/music

Right now, I'm doing:
mv music/genre/artist/*flac media/music/

Only, I'm doing that over and over.
The best things in life are free.
http://www.gentoo.org
Guy 1: Surely, you will fold with me.
Guy 2: Alright, but don't call me Shirley.
titan
Grand Gerbil Poohbah
 
Posts: 3276
Joined: Mon Feb 18, 2002 6:00 pm
Location: Great Smoky Mountains

Re: Need to move files but not directories

Postposted on Tue Sep 29, 2009 4:08 pm

Since it's just a one time move I'd write a simple bash for loop to automate your mv command. Something like:

Code: Select all
#!/bin/bash
TOP_DIR=/music
NEW_DIR=/media/music

for i in `ls $TOP_DIR`; do
  if [ -d $i ]; then
    for j in `ls $TOP_DIR/$i`; do
      if [ -d $j ]; then
        mv $TOP_DIR/$i/$j/*.flac $NEW_DIR/
        mv $TOP_DIR/$i/$j/*.ogg $NEW_DIR/
        mv $TOP_DIR/$i/$j/*.mp3 $NEW_DIR/
      fi
    done
  fi
done


you might want to test this before you use it, I tossed this off from memory
ekul
Gerbil
 
Posts: 81
Joined: Thu Jan 17, 2008 12:25 pm

Re: Need to move files but not directories

Postposted on Tue Sep 29, 2009 4:38 pm

MS Command Shell specific procedure deleted

Please Pardon me for not paying attention.
Last edited by PFarkas on Tue Sep 29, 2009 4:48 pm, edited 1 time in total.
PFarkas
Gerbil In Training
 
Posts: 1
Joined: Sun May 23, 2004 6:41 pm

Re: Need to move files but not directories

Postposted on Tue Sep 29, 2009 4:41 pm

Or a one-liner:
Code: Select all
find . -type f | egrep '\.flac$|\.mp3$|\.ogg$' | sed -e 's:^:mv ":;s:$:" destination-folder-name:' | bash

There's probably a less convoluted way to do it with xargs, but the above was the first thing I came up with.

Leave the final "| bash" off if you want to see what it is going to do before letting it loose on your files.
(this space intentionally left blank)
just brew it!
Administrator
Gold subscriber
 
 
Posts: 36917
Joined: Tue Aug 20, 2002 9:51 pm
Location: Somewhere, having a beer

Re: Need to move files but not directories

Postposted on Tue Sep 29, 2009 4:42 pm

PFarkas wrote:Try this. It's pretty straightforward.

FOR /R %i in (*.mp3) do Move "%i" \destination



Where \destination is the target for your files.

This will perform a MOVE operation on all of the files with a .MP3 extension to the target directory.

If you're skittish, you could replace Move with Copy, which would, of course, create a copy.

If you want to move ALL the files, replace *.MP3 with *.*

That would be all well and good if he was running Windows. This is the Linux forum.
(this space intentionally left blank)
just brew it!
Administrator
Gold subscriber
 
 
Posts: 36917
Joined: Tue Aug 20, 2002 9:51 pm
Location: Somewhere, having a beer

Re: Need to move files but not directories

Postposted on Tue Sep 29, 2009 4:51 pm

Caveat: My previous example will lose files if there are any name collisions. So be certain there are no duplicate names first...
(this space intentionally left blank)
just brew it!
Administrator
Gold subscriber
 
 
Posts: 36917
Joined: Tue Aug 20, 2002 9:51 pm
Location: Somewhere, having a beer

Re: Need to move files but not directories

Postposted on Tue Sep 29, 2009 7:51 pm

just brew it! wrote:Caveat: My previous example will lose files if there are any name collisions. So be certain there are no duplicate names first...

Thanks, that did the trick beautifully.

I had already done the most difficult part by hand. (There was still a lot to move over and JBI's one liner saved me another hour.) It was this mess of a directory of music that I some how inherited. No idea where it came from, but I've forbade my gf from ever downloading things that aren't free (as in beer). And, she's stuck to it. (She's a good girl.)

There were lots of duplicates, but using mv -u helps a lot. I tried to insert that switch into the one liner you gave me, JBI, but it threw back an error. I really need to learn those things, sed, awk or whatever. (My BASH learning is coming along pretty well.)

The BASH script I was given a little earlier did nothing. I'm sure I screwed up the input in some way. And, obviously, the MS script I was given really did nothing. :D
The best things in life are free.
http://www.gentoo.org
Guy 1: Surely, you will fold with me.
Guy 2: Alright, but don't call me Shirley.
titan
Grand Gerbil Poohbah
 
Posts: 3276
Joined: Mon Feb 18, 2002 6:00 pm
Location: Great Smoky Mountains

Re: Need to move files but not directories

Postposted on Tue Sep 29, 2009 8:12 pm

The "find <stuff> | sed <stuff> | bash" idiom is quite useful for arbitrary batch processing of files. The neat thing about it is you just leave the final "| bash" off while you play around with it to get it right; that way the commands get echoed to the terminal window instead of being executed until you've got the find/sed stuff correct.

I'm by no means a sed expert, but you can handle a lot of tasks like this one just by understanding how egrep regular expressions and the sed "s" (substitute) command work.

One other final thought: The egrep part of the one-liner is case-sensitive. If any files had e.g. a ".MP3" (uppercase) extension, they would've been left behind. The "-i" switch to egrep would've made it case-insensitive.
(this space intentionally left blank)
just brew it!
Administrator
Gold subscriber
 
 
Posts: 36917
Joined: Tue Aug 20, 2002 9:51 pm
Location: Somewhere, having a beer

Re: Need to move files but not directories

Postposted on Tue Sep 29, 2009 10:07 pm

just brew it! wrote:Or a one-liner:
Code: Select all
find . -type f | egrep '\.flac$|\.mp3$|\.ogg$' | sed -e 's:^:mv ":;s:$:" destination-folder-name:' | bash

There's probably a less convoluted way to do it with xargs, but the above was the first thing I came up with.

An xargs solution (using notfred's suggestion of using find's built-in matching):
Code: Select all
find . \( -name '*mp3' -o -name '*flac' -o -name '*ogg' \) -type f -print0 | xargs -n1 -I@ -0 mv @ destination-folder-name

or, for one total mv invocation rather than one per file,
Code: Select all
find . \( -name '*mp3' -o -name '*flac' -o -name '*ogg' \) -type f -print0 | xargs -0 mv -t destination-folder-name

One thing that I did notice is that find's -name matching interacts differently with odd unicode characters in filenames when I compare to egrep's matching.
bitvector
Grand Gerbil Poohbah
 
Posts: 3234
Joined: Wed Jun 22, 2005 3:39 pm
Location: Mountain View, CA

Re: Need to move files but not directories

Postposted on Wed Sep 30, 2009 12:48 am

Heh... the xargs solution isn't really that much easier to understand (and is actually longer) than my solution. I think I'll stick with my find/sed/bash pipeline method for stuff like this! :lol:
(this space intentionally left blank)
just brew it!
Administrator
Gold subscriber
 
 
Posts: 36917
Joined: Tue Aug 20, 2002 9:51 pm
Location: Somewhere, having a beer

Re: Need to move files but not directories

Postposted on Wed Sep 30, 2009 7:02 am

Why | bash or xargs when you can -exec on the find? To test first I add an echo on the commands that will be run.
notfred
Grand Gerbil Poohbah
 
Posts: 3650
Joined: Tue Aug 10, 2004 9:10 am
Location: Ottawa, Canada

Re: Need to move files but not directories

Postposted on Wed Sep 30, 2009 9:17 am

just brew it! wrote:Heh... the xargs solution isn't really that much easier to understand (and is actually longer) than my solution. I think I'll stick with my find/sed/bash pipeline method for stuff like this! :lol:

Well, I primarily prefer the "purity" of the find ... -print0 | xargs -0 approach (or find ... -exec as notfred suggested) because this is what it was designed for: xargs takes the filenames and throws them into exec with the program directly before the shell gets a chance to molest special characters. With your | bash solution, you are building up lines of text to be executed as shell commands, so they are subject to globbing and escaping and what have you. Some filenames can cause this to explode if the text in the filename interacts poorly with the shell or any of the other text you put in your commands. Consider what happens in your solution when you have a file named:
Code: Select all
james brown "the boss".mp3

The quotes in the filename close the quotes in your textual command and you get:
Code: Select all
mv "./mp3s/james brown "the boss".mp3" destination-folder-name
which now has spaces and looks like two separate files, failing to move. It's not really a big deal in this case, but sometimes such interactions can cause the command to do something unexpectedly nasty. Or alternately:
Code: Select all
Although I Dropped $100000 (I Found a Million Dollars in Your Smile).mp3
or many other uses of $ will cause the shell to manhandle it as an environment variable (since you used double quotes in your constructed commands rather than single quotes).

And notfred, I'd say the primary reason to prefer xargs to -exec on find is that -exec on find executes per file, whereas xargs gives you the opportunity to collect a bunch of files and execute the command once or a smaller number of times (or in increments of N). I agree if you're doing -n1 with xargs you could probably just use -exec.
bitvector
Grand Gerbil Poohbah
 
Posts: 3234
Joined: Wed Jun 22, 2005 3:39 pm
Location: Mountain View, CA

Re: Need to move files but not directories

Postposted on Wed Sep 30, 2009 10:25 am

Yup, agreed on if it's a lot of time then xargs is faster for only invoking once (or at least chunking). However the problem with solutions involving | here is what happens if nothing is found? You can fix it on xargs with -r but you have to be really careful that some of the other options don't end up with a mangled command line that does something that you don't want. find with -exec only executes on an actual find.
notfred
Grand Gerbil Poohbah
 
Posts: 3650
Joined: Tue Aug 10, 2004 9:10 am
Location: Ottawa, Canada

Re: Need to move files but not directories

Postposted on Thu Oct 01, 2009 11:06 am

I'm telling you, Foobar2000. Runs under wine beautifully (or you can mount the linux partition under windows).

Has a nice gui and supports file name pattern specifications.

http://wiki.hydrogenaudio.org/index.php ... operations
Image
Nitrodist
Grand Gerbil Poohbah
 
Posts: 3280
Joined: Wed Jul 19, 2006 12:51 am
Location: Minnesota

Re: Need to move files but not directories

Postposted on Thu Oct 01, 2009 5:29 pm

Now that I think about it, I could have written a Perl script to do the trick. The answer just came to me a moment ago. Blast my slow thinking brain!
The best things in life are free.
http://www.gentoo.org
Guy 1: Surely, you will fold with me.
Guy 2: Alright, but don't call me Shirley.
titan
Grand Gerbil Poohbah
 
Posts: 3276
Joined: Mon Feb 18, 2002 6:00 pm
Location: Great Smoky Mountains


Return to Linux, Unix, and Assorted Madness

Who is online

Users browsing this forum: No registered users and 3 guests