How to move some files but preserve the directory tree?

So, I have a bunch of ogg files that I moved to mp3 (I don’t want to start a format/encoder war, I just did it), I wanted to move the old ogg files, I didn’t delete them because probably I need them in the future. To move the files apart the easiest way could be using find and xargs:


find . -iname "*ogg" -print0 |xargs -0 -I {} mv {} /dest/folder/

The problem with this is that all those ogg files would be in /dest/folder/ all together, and I want to have them each in the corresponding subfolder, I was looking and found that some uses “cp –parents” unfortunately it seems that the cp in OS X does not include that.

What I ended up doing.

If you create a package file (.tar for example), the directories are preserved, so, for me the trick was using tar for that purpose.


find . -name "*ogg" -print0 | xargs -0 tar cvf - |(cd /dest/folder/ ; tar xfp -)

You’ll see all those ogg files in the screen as they are “copied” to the destination folder. later you can remove the files with find again.


find . -iname "*ogg" -delete

 

I assume there is a way to remove the files as soon as they have been added to the tar file.

Loading

Find (and remove files) with find

terminal

find is a great tool to find things, but not only to find them, but to work on them. I have a small collection of music, which I presume at some point will be removed from my computer hard drive (maybe if I can get a new one it won’t be there at all) because I mostly listen to music from internet and I have a copy of the music in a external hard drive.

Today I imported the folder where the music is to iTunes again, and it created playlists that I don’t remember to have them before. That is because there were several m3u files there (winamp playlists), there are around 5k files in that directory tree and I don’t want to spend my time looking for m3u files, so, let the computer do the job.

With find is easy to find files, not by their name but by their type the f is for file.

find . -type f

Ok, but that will include all the “mp3” which are files, so if I make use of -iname to find by name,  how can I do the opposite?, well, like in most programming languages, you can negate by using the exclamation symbol !.

find . -type f ! -iname "*mp3"

And add some more extensions.

find . -type f ! -iname "*mp3" ! -iname "*ogg" ! -iname "*m4a" ! -iname "*wma"

That will give me all files that are not mp3, ogg, m4a or wma. Then just use the -delete parameter to as find to delete them.

find . -type f ! -iname "*mp3" ! -iname "*ogg" ! -iname "*m4a" ! -iname "*wma" -delete

And… they are gone.

How would you do it?. Share it in the comments.

Loading