<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<title></title>
<style type="text/css">
<!--
body{margin-left:10px;margin-right:10px;margin-top:10px;margin-bottom:10px;}
-->
</style>
</head>
<body marginleft="10" marginright="10" margintop="10" marginbottom="10">
<font face="Arial" size="+0" color="#000000" style="font-family:Arial;font-size:10pt;color:#000000;"><b>CentOS mailing list <<a href="mailto:centos@centos.org">centos@centos.org</a>> writes:<br />
</b></font><span style="background-color:#d0d0d0;"><font face="Geneva" size="-1" color="#000000" style="font-family:Geneva;font-size:9pt;color:#000000;">I had at one point copied a large number of files between drives and did <br />
not use the -p and thus the timestamps were all set to the date of the copy.<br />
<br />
I did not catch this, and deleted the source.  So I 'lived' with it and <br />
have since changed many files.<br />
<br />
Well, yesterday I found a good backup of many of those files and I want <br />
to restore them to their proper dates.<br />
<br />
cp -p -u is exactly the opposite of what I want.  I want to copy only if <br />
the source files have an earlier date than the destination files.<br />
<br />
The source files are just an old copy on another drive that I found when <br />
cleaning up things...<br />
<br />
</font></span><font face="Lucida Sans Typewriter" size="+0" color="#000000" style="font-family:Lucida Sans Typewriter;font-size:12pt;color:#000000;"><br />
SRC=/my/restored/files<br />
DST=/the/working/tree<br />
export SRC DST<br />
find "$SRC" -type f -print | while read A; do [ "${A}" -ot "${DST}${A##$SRC}" ] && /bin/touch -r ${A} "${DST}${A##$SRC}"; done<br />
<br />
Note that using this syntax, the two variables cannot be set in-place on the same command line as "find ..."; it only seems to work for me if they're exported as environment variables.<br />
<br />
A more expanded version of the same, with commentary:<br />
<br />
cat > fix_timestamps.sh << __EOF__<br />
#!/bin/sh<br />
### Scans a source directory for files, setting the dates of same-named files in a target directory<br />
### Adam Thompson <<a href="mailto:athompson@sjsd.net">athompson@sjsd.net</a>> 2007-Aug-07<br />
# Source directory - no need for trailing slash<br />
SRC=/my/restored/files<br />
# Target directory - no need for trailing slash<br />
DST=/the/working/tree<br />
# Locate all _files_ only<br />
find "$SRC" -type f -print | (  # subshell not necessary, only here for readability<br />
        # read each line of input from the pipe into $A<br />
        while read A; do <br />
        # if's can be shortened to && most times<br />
        # Proceed only if source file is OlderThan target file<br />
        if [ "${A}" -ot "${DST}${A##$SRC}" ]; then<br />
                # Proceed only if target file exists<br />
                # Probably being paranoid, since -ot should have already failed...<br />
                if [ -f  "${DST}${A##$SRC}" ]; then<br />
                        # Use "touch" to reset the timestamp on the file \<br />
                        #   instead of re-copying the data<br />
                        # "-r" == "--reference", uses the source file's \<br />
                        #   timestamp to set the destination file's timestamp<br />
                        /bin/touch -r ${A} "${DST}${A##$SRC}"<br />
                fi<br />
        fi<br />
        done<br />
)<br />
__EOF__<br />
<br />
<br />
Obviously the one-liner above is going to be marginally faster, especially on slower CPUs, but the difference should be minimal - bash isn't that much of a CPU hog.<br />
<br />
-Adam Thompson<br />
 Divisional IT Department,  St. James-Assiniboia School Division<br />
 150 Moray St., Winnipeg, MB, R3J 3A2<br />
 <a href="mailto:athompson@sjsd.net">athompson@sjsd.net</a> / tel: (204) 837-5886 x222 / fax: (204) 885-3178<br />
</font>
</body>
</html>