Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Batch move files from multiple sub-directories UNIX
In a iPhoto Extraction thread on the macosxhints forum site, kerim discusses some issues he was having with iPhoto. For some reason, the photos in the iPhoto Library weren't showing up in iPhoto itself, so he wanted to copy them from the iPhoto directories to one new "flattened" directory.

iPhoto stores images in subdirectories organized by year and date, and kerim was wondering how to move all of the images at once. He had tried a Sherlock search on "*.JPG" in the iPhoto Library, but the program kept crashing when he tried to move the files from the results window (probably due to the 1700 items in the search results!). So he was looking for a Terminal solution.

Through some stumbling on my own, and with a large bit of help from a buddy, I came up with one solution (I'm sure there are other, more elegant, ways to do this). In the Terminal, first "cd" to the highest directory that contains all the files you wish to affect. Then type:
  % cp `find . -name "*.jpg"` /path/to/new/folder
This will copy any files ending in ".jpg" (in any directory at or below the current level) to the location you specify in the "/path/to..." portion of the command. For the destination, make sure you use a path which is outside (different drive, anywhere else "above" the current directory, etc.) of the directory you're working in!

This hint is probably "non-news" to the experienced UNIX users out there, but it was new to me, so it may help others as well...
  • Currently 3.00 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (1 vote cast)

Batch move files from multiple sub-directories | 7 comments | Create New Account
Click here to return to the 'Batch move files from multiple sub-directories' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
A similar technique
Authored by: pck on Jul 03, '02 01:25:50AM

Much of this goes back to basic (or at least standard) shell scripting.

The main problem with the as-submitted command is that identical instance
numbers in different dated-subdirectories will over-write each other.

A possible solution would be something like this (yes, there are more efficient

	% sh    [or, as I prefer, zsh, this is to get to a familiar scripting syntax]
	% cd ; mkdir some-image-dir ; cd some-image-dir
	% path_to_iphoto_dir="../Pictures/iPhoto Library" ; find $path_to_iphoto_dir -name *.jpg | while read file ; do 
		new=`echo $file | sed -e "s,$path_to_iphoto_dir/,,;s,/,-,g"` ; echo cp "$new" . ; done
Remove the 'echo' before the 'cp' to actually execute the copy. I'll leave deciphering it to the typical "exercise for the interested reader".

[ Reply to This | # ]
A similar technique
Authored by: mr. applescript on Jul 03, '02 12:52:35PM

Those new to Mac OS X might not realize that the shell is not the only way to automate the computer. Try using AppleScript. For example, here's the script for moving all the JPEG images in an entire directory to another folder. The variables (this_folder and target_folder) contain refs to the cooresponding directories.

-- Sal

tell application "Finder"
move (every file of the entire contents of this_folder whose name extension is "jpg") to the target_folder
end tell

[ Reply to This | # ]
A similar technique
Authored by: kerim on Jul 03, '02 07:29:23PM

Does this applescript solution work recursively? The issue was that iPhoto stores its photos in many many subfolders. If everything were in the same folder one could simply drag and drop the whole folder. I'm sure this is possible in Applescript, but I found that the shell sped things up considerably. Just think about all the spinning color wheels you get when you try to select a lot of items in the finder and do something with them! All those Aqua tricks (transparnet dragging) really don't scale very well when you are doing operations on thousands of files. It would be interesting to compare the speed using Applescript and using the shell ...

[ Reply to This | # ]
odd filenames
Authored by: mervTormel on Jul 03, '02 02:53:29AM

another problem with the cp `find results` is that it will gak on filenames with spaces or otherwise chars out of the normal char range ( [A-z][0-9] _ ). special chars in the filename need to be quoted to be passed to cp without poison.

see the forums thread link in the hint above for chicanery that will make the results more better.

[ Reply to This | # ]
odd filenames
Authored by: clith on Jul 04, '02 01:57:47PM
Normally you would use "xargs" together with "find" to handle strange, space-filled names. However, the version of xargs shipped with MacOS X is vastly underpowered compared to the Linux [GNU] version. In the Linux version I could write:
% find . -name '*.jpg' -print0 | xargs -0 -t -i mv '{}' /path/to/new/folder
but the MacOS X version does not have the "-i" flag that lets you use '{}' as a token to represent the filename, so you would have to use perl (since there is no way to move the destination dir to the end of the "mv" command using xargs):
find . -name '*.jpg' -print0 \\ | perl -0 -ne 'push @files, $_; END { print "mv \\"", join("\\" \\"", @files), "\\" /path/to/new/folder\\n"; }'
Now that just prints out a nice big "mv" command for you and you can copy-and-paste your way to happiness. Anything further is left as an excercise for the reader. :-)

[ Reply to This | # ]
More elegant and space-saving!
Authored by: Palijn on Jul 03, '02 09:09:09AM
If you want to save the space that you use when copying the files in the above method, just use "ln" instead of "cp" .

Note that you MUST swap the destination and source arguments for this to work (the opposite of the "cp" syntax).

This creates hard links to the files, effectively letting you (or iPhoto) access them from the directory you want.
Note that a file is deleted from the filesystem only when all hard links reffering to it are deleted!

As this was used to duplicate a pictures library, I thought it could be useful to some to avoid duplicating the space used on the disk. By the way, since no data is moved by "ln", it is incredibely faster! :-)


[ Reply to This | # ]
Correction to the above
Authored by: Palijn on Jul 04, '02 07:24:46PM
Well, folks, I hate to admit it, but I must have drunk a bit too much that day when I wrote the comment.
Actually, the whole method is still valid and much more space- and time-efficient than copying the files.
The thing that is false is, you don't have to invert the "cp" arguments.
Anyway, a quick inspection on the man ln page would already have corrected my preceding note on that point! :-)

[ Reply to This | # ]