While copying data from my old storage on a Linux computer to the new (linux-based) NAS, I accidentially failed with getting the properties (most important: the modify dates) along to the new location. I also continued to use/modify the files at the new location and hence, cannot just copy it all over again.

What I would like to do is a diff between files in the old vs. the new storage, and for those being identical, restore the properties from Linux storage to the NAS storage files.

Is there a clever way such as a script or a tool to do this? I could either run it on the Linux box or in worst case from a remote Windows computer.

Grateful for any suggestions. /Jon

  • You could run a cryptographic hash on the files (SHA1 maybe), compare both of each file's hashes and if identical touch -m the NAS file (with the appropriate date time settings). It would be a hack, but I think it would work. – Elliott Frisch Apr 24 '14 at 2:32
  • Hi Elliott, Thanks for the suggestion. Yes, I will probably have to spend a few hours to create a solution like this. I was hoping I could be lazy and make use of an already-existing tool for this but as a second option your idea is good. – Jon Apr 25 '14 at 5:44
up vote 0 down vote accepted

I just thought I'd better share the code i've come up with. While not being a bash programmer, there's a lot of knowledge available via Google so I believe this code will do the work for me. Basically what it does is:

  • Loop through all files and folders in the new location and for each:
    • check if the same file exist in the old location
      • If no, then write a log entry
      • If yes, does the timestamp (modify date) match?
        • Yes - nothing to do but write a log entry
        • No, timestamps does not match
          • Is it either a directory or is file content identical? Then reset timestamp to the timestamp of the file in the old location, and write a log entry
          • If file content differs, then the timestamps may do as well. Just write a log entry.

Code:

shopt -s globstar

NEWDIR="/home/jon"
OLDDIR="/tmp/jon_old"
LOGFILE=restoreDates_$(date "+%Y-%m-%d-%H%M%S").log

echo $LOGFILE > $LOGFILE

for f in "$NEWDIR"/** ; do
OLDFILE=$(sed -e "s/$NEWDIR/$OLDDIR/" <<< $f)

  # Does corresponding file exist in old directory?

  if [ -a "$OLDFILE" ] ; then

    # Do both files have the same modify date?
    if [ $(stat -c %Y "$f") -eq $(stat -c %Y "$OLDFILE") ] ; then
        echo "$OLDFILE already has same modify date/time as $f" >> $LOGFILE
    else

        # Is this a directory?
        if [ -d "$f" ]; then
            echo "$f is a directory, modify timestamp will be reset to that of $OLDFILE; $(stat -c %y "$OLDFILE")" >> $LOGFILE
            touch -r "$OLDFILE" "$f"
        else
            # Not a directory - Is old file equal to the new?
            if $(cmp --silent "$f" "$OLDFILE"); then
                # yes
                echo "$OLDFILE and $f are identic, modify timestamp will be reset to $(stat -c %y "$OLDFILE")" >> $LOGFILE
                touch -r "$OLDFILE" "$f"
            else # File has changed
                echo "$OLDFILE differs from $f , which must have changed" >> $LOGFILE
            fi
        fi
    fi
  else # File does not exist in old directory
    echo "$OLDFILE does not exist (but $f do)" >> $LOGFILE
  fi

done;

Any comments on the code are welcome.

  • My apologies for above presentation of the code - I was not able to bring it all into the code box... – Jon May 27 '14 at 20:58

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.