views:

1009

answers:

3

Anyone know of a command line utility (or one that can run as a command line) that will collect all the .jpg files in a directory tree to a single folder, only copying files that change?

I started with Renamer, which is great for renaming files in their current directories, but fell short when I tried to mangle the path. This is probably because I don't know Renamer that well. I ended up creating a text file directory dump, then using a REGEX find / replace to create a batch file, but this is hardly efficient nor automated.

The REGEX:

(G:\DIR\DIR\)([0-9]+\)([0-9]+\)([0-9]+\)([0-9]+\)(p[0-9]+.jpg)

changed this

G:\DIR\DIR\00\00\00\00\p0000000000.jpg

to this

G:\DIR\DIR\p0000000000.jpg

(copy \1\2\3\4\5\6 \1\6) in the batch file.

I need to run the whole thing as a scheduled task without a real person logging in. Not really looking for a Zip file because I don't want to disturb the system processor, plus most of the files will not change from day to day. This is more of a file sync.

A: 

I'm guessing you're on Windows from the path format.

I've not read the whole thing, but http://www.infionline.net/~wtnewton/batch/batguide.html#6a might help you.

The same page has dizzy.bat, (http://www.infionline.net/~wtnewton/batch/dizzy.bat) which should be trivial to edit to do what you want.

RoadieRich
+5  A: 

In a Windows command line you can do this:

for /R A %i IN (*.jpg) DO xcopy %i B /M

Where A is the source directory and B is the destination directory. You need to have command extentions enabled, which I believe is the default.

Martin Brown
Does this only copy files that change? That seems to be the tricky part.
Dennis Palmer
Fantastic answer.
Dr. Zim
@Dennis Palmer - In my edit I changed copy to xcopy with /M. /M only copies files with the archive attribute set and removes the arcive attribute from the original file. When the file changes the archive attribute should be re-applied by Windows.
Martin Brown
Why are you using /M here?Would adding /D at the end to only copy files whose source time is newer than the destination time?
Dennis Palmer
OK, you replied while I was researching it. Cool! Upvoting answer.
Dennis Palmer
I guess you could use /D. I just chose /M as it was first in the xcopy help text (/?). Infact using /D may be better as the Archive attribute is normally used by backup software and if the source directory is being backed using /M may cause an issue.
Martin Brown
It would be good to add /Y too, so that it automates confirmations to overwrite.
Dr. Zim
A: 

In a Unix environment I would use find or rsync (and maybe some features of the shell). Cygwin and MinGW come with find, maybe with rsync. You can also probably get a standalone port of find for Windows somewhere.

If the SOURCE shell variable is the directory containing subdirectories with files to copy, and the DEST shell variable is the directory to copy them to:

find $SOURCE -name \*.jpg -exec cp --update \{\} $DEST/ \;

find is by nature recursive. "-name \*.jpg" selects files that match that pattern. You can add additional conditions with -and. The --update option to the cp command (or -u) only bothers copying the file if changed or not yet copied. There are other options to cp that might be useful too.

If $SOURCE is the same as $DEST as in your DIR/DIR/ example, then find will also find the destination files (already copied), though this will be ok, cp will recognize that you are trying to copy the same file to itself and skip it, but if you want to avoid that wasted work you can use 'for' and 'if' (or something) to only run find on the subdirectories of DIR/DIR/.

You can also use rsync, which has options that can delete files from the destination directory if they have also been deleted from the source directory, and many other such variations.

Reed Hedges