Wed Aug 5 17:02:08 MDT 2015

An Update to DirMerge.sh for OS X

I forgot that OS X's find command is not the Gnu find command. So, the find command used by the DirMerge.sh script needs a tweak to run on OS X. Here is that tweak.

#!/bin/sh
awk '
BEGIN{
  dir1="\"" ARGV[1] "\"/"
  dir2="\"" ARGV[2] "\"/"
  readdir(dir1, lista, typea)
  readdir(dir2, listb, typeb)
  for(filea in lista){
    if(filea in listb){
      if(typea[filea] == "f"){
        if(ckfile(dir1 "\"" filea "\"") != ckfile(dir2 "\"" filea "\"")){
          print "# " dir1 "\"" filea "\"" " " dir2 "\"" filea "\""
          print "# WARNING FILES DIFFER - CONTINUING - YOU NEED TO CHECK WHY!"
        } else {
           com[++ncom]="# files match " dir1 "\"" filea "\"" " " \
                        dir2 "\"" filea "\""
           com[++ncom]="/usr/bin/rm " dir1 "\"" filea "\""
        }
      }
    }else{
      if(typea[filea] == "d" ){
        dcom[++ndcom]="# directory needs to be created in the target"
        dcom[++ndcom]="mkdir -p " substr(dir2,1,length(dir2)-2) \
                       substr(filea,2) "\""
      } else {
        com[++ncom]="# file needs to be moved to the target"
        com[++ncom]="mv " substr(dir1,1,length(dir1)-2) substr(filea,2) \
                 "\"" " " substr(dir2,1,length(dir2)-2) substr(filea,2) "\""
      }
    }
  }
  if(!ncom && !ndcom){
    print "No updates required"
    exit
  }
  print "The following commands are needed to merge directories:"
  for(i=1;i<=ndcom;i++){
    print dcom[i]
  }
  for(i=1;i<=ncom;i++){
    print com[i]
  }
  print "Do you want to execute these commands?"
  getline ans < "/dev/tty"
  if( ans == "y" || ans == "Y"){
    for(i=1;i<=ndcom;i++){
      print "Executing: " dcom[i]
      escapefilename(dcom[i])
      system(dcom[i])
      close (dcom[i])
    }
    for(i=1;i<=ncom;i++){
      print "Executing: " com[i]
      escapefilename(com[i])
      system(com[i])
      close (com[i])
    }
  }
}
function ckfile(filename,   cmd)
{
    if (length(ck[filename])==0){
        cmd="cksum " filename
        cmd | getline ckout
        close(cmd)
        split(ckout, array," ")
        ck[filename]=array[1]
    }
    return ck[filename]
}
function escapefilename(name){
  gsub("\\$", "\\$", name)     # deal with dollars in filename
  gsub("\\(", "\\(", name)     # and parentheses
  gsub("\\)", "\\)", name)
}
# OS X does not have the -ls option for find, so work around this using stat
function readdir(dir, list, type, size,        timestamp, ftype, fsize, name){
  cmd="cd " dir ";find . -exec stat -r {} \\;"
  print "Building list of files in: " dir
  while (cmd | getline > 0){
    timestamp=$10
    if(substr($3,1,2)=="01"){
      ftype="f"
    } else if (substr($3,1,2)=="04") {
      ftype="d"
    } else {
      ftype="unknown"
    }
    fsize=$8
    for(i=1;i<=15;i++){
      $(i)=""
    }
    name=substr($0,16)
    if(name==".")continue
    list[name]=int(timestamp)
    type[name]=ftype
    size[name]=fsize
  }
  close(cmd)
}' "$1" "$2"

Posted by ZFS | Permanent link | File under: bash