Advertisement
rccharles

revised-consolidate-gnu-generalized.command

Feb 12th, 2018
594
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Bash 21.58 KB | None | 0 0
  1. #!/bin/bash
  2.  
  3. # Purpose of this script:
  4. #
  5. # Accurately eliminate duplicate files within a given folder. Optionally, consolidate all files
  6. # to a common folder.  Duplicate names within the consolidate folder will be made unique.
  7. #
  8. # Methodology:
  9. # Find folders within a specified top folder which are not bundles. Find files
  10. # within each found folder [and within subfolders ]. because each folder is
  11. # handled individually.)
  12. # Find potential bundles and checksum their entire content as one item.
  13. # Get MD5 checksums for each item and save an index of all checksums and
  14. # filepaths. Sort the index by checksum.  Compare each
  15. # item's checksum and if a duplicate is found, move the duplicate to the trash.
  16. # Compare each item's name and if a duplicate is found, append incrementing #X
  17. # to the name prior to the last period (as in "Filename #2.jpg")
  18. # Ignore iTunes and iPhoto folders
  19. #
  20. # Optionally move files and potential bundles to the top-level folder
  21. # Delete .DS_Store, .FBCIndex*, and .FBCSemaphoreFile files and subsequently
  22. # delete empty subfolders.  Optionally regroup map files into folders based on
  23. # the name of .frq file if found, or .shp file
  24. #
  25. # This script is a partial rewrite of the code from JulieJulieJulie's Consolidate17 script.  
  26. # See:
  27. #   http://discussions.apple.com/message.jspa?messageID=11577992#11577992
  28. #
  29. #   Copyright 2010 rccharles
  30. #
  31. #   GNU General Public License
  32. #
  33. #   This program is free software: you can redistribute it and/or modify
  34. #   it under the terms of the GNU General Public License as published by
  35. #   the Free Software Foundation,  version 3
  36. #
  37. #   This program is distributed in the hope that it will be useful,
  38. #   but WITHOUT ANY WARRANTY; without even the implied warranty of
  39. #   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  40. #   GNU General Public License for more details.
  41. #
  42. #   For a copy of the GNU General Public License see
  43. #   <http://www.gnu.org/licenses/>.
  44. #
  45. copyRight="Copyright (c) 2010 & 2018 rccharles. GNU General Public License."
  46. #
  47. #
  48.  
  49.  
  50. # debug info
  51. export PS4='+(${BASH_SOURCE}:${LINENO}):'
  52.  
  53. ## not in the tiger version of bash ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
  54.  
  55.  
  56. ##########
  57. ### Functions (subroutines which can be called by name)
  58.  
  59. function helpHelpIsAllINeed () {
  60. echo
  61. echo "${savedCommandName##*/} [ options ] [ directory-to-compress ]"
  62. echo
  63. echo "options:"
  64. echo "-h  Display quick help."
  65. echo
  66. echo "-m  Moving files is disabled."
  67. echo "-M  Move files to top level."
  68. echo
  69. echo "-r  Regrouping map files is disabled."
  70. echo "-R  Regroup map files."
  71. echo
  72. echo "-V  Display very detailed messages."
  73. echo
  74. echo "example:"
  75. echo "    ./${savedCommandName##*/} -mrV /Users/mac/cons/see"
  76. echo
  77. }
  78.  
  79. function Show_Time () {
  80. let currentRunTime="$( date +%s ) - ${Seconds_since_the_epoch_start}"
  81. let stepRunTime=currentRunTime-previousRunTime
  82. echo "  Elapsed time in seconds since start of processing: ${currentRunTime}" \
  83.      "   Time of this step: ${stepRunTime}"
  84. echo
  85. let previousRunTime=currentRunTime
  86. }
  87.  
  88. function echoTrashInfo () {
  89.     echo " -${trashFileName}"
  90.     echo "${fileName} > ${trashFileName}" \
  91.         >>"${saveFolder}/Consolidate_Trashed_List_${runDateTime}.txt"
  92.    
  93.     case "${fileType}" in
  94.         f ) let trashFileCount+=1
  95.             ;;
  96.         d ) let trashDirectoryCount+=1
  97.             ;;
  98.         * ) Echo
  99.             Echo "Error --- Error in echoTrashInfo. fileName=${fileName};"
  100.             Echo "Error --- fileType=${fileType};"
  101.             Echo
  102.             ;;
  103.     esac   
  104.            
  105. }
  106.  
  107. declare     folder  \
  108.             MainFolder  \
  109.             MoveFiles="Question"    \
  110.             RegroupMapFiles="Question"  \
  111.             runDateTime=$(date '+%Y-%m-%d_%H.%M')   \
  112.             Seconds_since_the_epoch_start  
  113.                
  114.            
  115. declare -x  tab=$'\t'   \
  116.             trashFolder \
  117.             verbose="Yes"   \
  118.             veryVerbose="Yes" \
  119.             whereIsTrash
  120.            
  121.            
  122. declare -i  count=0 \
  123.             offsetMainFolder \
  124.             currentRunTime \
  125.             previousRunTime=0 \
  126.             stepRunTime \
  127.             trashDirectoryCount=0 \
  128.             trashFileCount=0
  129.            
  130. declare -a  filePath    \
  131.             fileName    \
  132.             fileSum     \
  133.             folders
  134.    
  135.  
  136. savedCommandName="$0"
  137. echo
  138. echo "${savedCommandName} script revised $(GetFileInfo -m $0)"
  139. echo
  140. bigVersion="Lizard 4"
  141.  
  142. echo "=============================================================="
  143. echo
  144. echo "       ${bigVersion}"
  145. echo "                    ${bigVersion}"
  146. echo "                                 ${bigVersion}"
  147. echo
  148. echo "=============================================================="
  149. echo
  150. echo "${copyRight}"
  151. echo
  152.  
  153.    
  154. # If the utility md5 is not present then just quit, it's needed for the checksums.
  155. [ ! -x /sbin/md5 ] && exit 2
  156.  
  157. # Check for command-line options used when calling the script
  158. if [ $# -gt 0 ] ; then
  159.     while getopts "hmMrRV" Option ; do
  160.         case "${Option}" in
  161.         h ) helpHelpIsAllINeed
  162.             echo "Bye for now."
  163.             exit 7
  164.             ;;
  165.         m ) echo "-m argument used on command line, moving files is disabled."
  166.             echo  
  167.             MoveFiles="No"
  168.             ;;
  169.         M ) echo "Moving files.  -M argument used on command line."
  170.             echo  
  171.             MoveFiles="Yes"
  172.             ;;
  173.         r ) echo "-r argument used on command line, regrouping map files is disabled."
  174.             echo
  175.             RegroupMapFiles="No"
  176.             ;;
  177.         R ) echo "Regrouping map files. -R argument used on command line."
  178.             echo
  179.             RegroupMapFiles="Yes"
  180.             ;;
  181.         V ) echo "Display very detailed messages. -V argument used on command line."
  182.             echo
  183.             veryVerbose="Yes"
  184.             ;;
  185.         * ) echo "Unknown argument among arguments $* on command line."
  186.             helpHelpIsAllINeed
  187.             exit 6
  188.             ;;
  189.         esac
  190.     done
  191. fi
  192.  
  193. # We're done with switches / options from the command line
  194. shift $(($OPTIND - 1))
  195.  
  196. # Main folder can be declared on the command line or interactively
  197. MainFolder="${1}"
  198.  
  199. # If the main folder doesn't exist, prompt once, then just quit if it's still not there.
  200. if [ ! -d "${MainFolder}" ] ; then
  201.     echo "Folder not specified. Type the path to the top-level folder or drag"
  202.     echo "it into this Terminal window, then click back in this window and press return:"
  203.     read MainFolder
  204.     echo
  205. fi
  206.  
  207. [ ! -d "${MainFolder}" ] \
  208.     && echo "Folder not found. Was ${MainFolder}" \
  209.     && exit 4
  210.    
  211. [ "${MainFolder}" = "/" ] \
  212.     && echo "You must be crazy." \
  213.     && exit 5
  214.  
  215. echo "Holding down Control-c on the keyboard will stop this script in an emergency."
  216. echo
  217.  
  218. if [ "${MoveFiles}" = "Question" ] ; then
  219.     echo "WARNING: allowing the script to move files could cause problems!"
  220.    
  221.     echo
  222.     echo "Do you want to move all files and bundles to the top level at the end of the run?"
  223.     read -n1 -p "Press 'n' to NOT move files and keep the folder structure intact; otherwise press any key. "
  224.     if [ "${REPLY}" = "n" -o "${REPLY}" = "N" ] ; then
  225.         MoveFiles="No"
  226.     else
  227.         MoveFiles="Yes"
  228.     fi
  229.     echo
  230.  
  231.    
  232. fi
  233.  
  234. if [ "${RegroupMapFiles}" = "Question" ] ; then
  235.     echo "Do you want to disable regrouping of map files into folders based on the .shp filename?"
  236.     read -n1 -p "Press 'n' to NOT regroup map files; otherwise press any key. "
  237.     if [ "${REPLY}" = "n" -o "${REPLY}" = "N" ] ; then
  238.         RegroupMapFiles="No"
  239.     Else
  240.         RegroupMapFiles="Yes"
  241.     fi
  242.     echo
  243. fi
  244.  
  245. [ "${veryVerbose}" = "Yes" ] \
  246.     && ulimit -a \
  247.     && df \
  248.     && echo
  249.  
  250. [ "${veryVerbose}" = "Yes" ] \
  251.     && echo "MainFolder=${MainFolder};"
  252.  
  253. # get physical path
  254. if [ -d "$MainFolder" ]; then
  255.     pushd $PWD
  256.     cd "$MainFolder"
  257.     MainFolder=$( /bin/pwd -P )
  258.     popd
  259. else
  260.     # just to be sure.
  261.     echo "You need to supply a directory name for ${MainFolder}"
  262.     exit 8
  263. fi 
  264.    
  265. let offsetMainFolder="${#MainFolder}"-1
  266.  
  267. # Ensure that the path is in a consistant format. i.e. no //
  268. # drop trailing directory separator if needed
  269. [ "${MainFolder:${offsetMainFolder}}" = "/" ] \
  270.     && MainFolder="${MainFolder:0:${offsetMainFolder}}"
  271.  
  272. # Place all created files in one directory.
  273. saveFolder="${MainFolder}/saved--Consolidated--Data"
  274.  
  275. # Figure out the trash folder name. Each user has his or her own trash folder.
  276. # Each volume has a different trash folder. On the startup drive,
  277. # the trash folders are in the users home folder. On the other volumes, the
  278. # trash folder contains a folder with the user id for each user.
  279. #
  280. # This isn't perfect.  
  281. if [ $( echo -n "${MainFolder:0:7}" | tr '[:upper:]' '[:lower:]' ) \
  282.         = "/users/" ] ; then
  283.     whereIsTrash="u"
  284.     trashFolder="${HOME}/.Trash"
  285. elif [  $( echo -n "${MainFolder:0:9}" | tr '[:upper:]' '[:lower:]' ) \
  286.         = "/volumes/" ] ; then
  287.     whereIsTrash="v"
  288.     diskName="${MainFolder:9}"
  289.     diskName="${diskName%%/*}"
  290.     trashFolder="/Volumes/${diskName}/.Trashes"
  291.     if [ ! -d ${trashFolder} ] ; then
  292.         # Needs work.  Should be ok, since folder is created when formated.
  293.         Echo "Creating trash folder. ${trashFolder};"
  294.         saveUmask=$( umask )
  295.         mkdir ${trashFolder}
  296.         umask ${saveUmask}
  297.     fi
  298.     currentId=$( id -ru )
  299.     trashFolder="${trashFolder}/${currentId}"
  300.     if [ ! -d ${trashFolder} ] ; then
  301.         Echo "Creating user's individual trash folder. ${trashFolder};"
  302.         saveUmask=$( umask )
  303.         umask 077
  304.         mkdir ${trashFolder}
  305.         umask ${saveUmask}
  306.     fi
  307. else
  308.     echo "Not sure where main folder resides. defulat to ~/.Trash"
  309.     whereIsTrash="u"
  310.     trashFolder="${HOME}/.Trash"
  311. fi
  312.  
  313.  
  314. [ "${veryVerbose}" = "Yes" ] \
  315.     && echo "MainFolder=${MainFolder};" \
  316.     && echo "saveFolder=${saveFolder};" \
  317.     && echo "trashFolder=${trashFolder};"
  318.  
  319.  
  320.  
  321. [ ! -d "${saveFolder}" ] \
  322.     && mkdir "${saveFolder}"
  323.  
  324. #Housekeeping for Index files.
  325.  
  326. # If the index archive file does not exist,
  327. # create it so that it will be there for sorting and merging later
  328. [ ! -e "${saveFolder}/Index_Archive.txt" ] \
  329.     && touch "${saveFolder}/Index_Archive.txt"
  330.  
  331. # If the index file exists, archive it and be sure to delete the index.
  332. if [ -e "${saveFolder}/Index.txt" ] ; then
  333.     echo "----------------------------" >> "${saveFolder}/Index_Archive.txt"
  334.     cat "${saveFolder}/Index.txt" >> "${saveFolder}/Index_Archive.txt"
  335.     rm "${saveFolder}/Index.txt"
  336. fi
  337.  
  338. touch "${saveFolder}/Index.txt"
  339.  
  340. # In case of a crash, clean up from previous run.
  341. [ -e "${saveFolder}/names.txt" ] \
  342.     && rm "${saveFolder}/names.txt"
  343.    
  344. touch "${saveFolder}/names.txt"
  345.  
  346. # Ensure that the trashed list file will exist even if no files were trashed
  347. [ ! -e "${saveFolder}/Consolidate_Trashed_List_${runDateTime}.txt" ] \
  348.     && touch "${saveFolder}/Consolidate_Trashed_List_${runDateTime}.txt"
  349.  
  350. [ "${veryVerbose}" = "Yes" ] \
  351.     && ls -l "${saveFolder}/Index.txt" \
  352.     && ls -l "${saveFolder}/names.txt" \
  353.     && ls -l "${saveFolder}/Consolidate_Trashed_List_${runDateTime}.txt" \
  354.     && ls -ld "${trashFolder}" \
  355.     && ls -ld "${trashFolder}/.." \
  356.     && echo
  357.  
  358. echo "--> Deleting .DS_Store and .FBC files from subfolders."
  359. find -d "${MainFolder}" -type f \( -name ".DS_Store" -o -name ".FBCIndex*" \
  360.     -o -name ".FBCSemaphoreFile" \) -delete
  361.  
  362.  
  363. if [ "${veryVerbose}" = "Yes" ]  ; then
  364.     echo "Gathering debug information.  May take a moment.  Counting files."
  365.     fileCountBefore=$( find ${MainFolder} -type f \
  366.         \! \(  -path "${saveFolder}" -o -path "${saveFolder}/*" \) \
  367.         | wc -l )
  368.     trashCountBefore=$( find ${trashFolder} -type f | wc -l )
  369. fi
  370.  
  371. # Set the internal field separator to newline to preserve spaces in file paths
  372. IFS=$'\n'
  373.  
  374. # Set the start time now that the user interaction is done
  375. Seconds_since_the_epoch_start=$( date +%s )
  376.  
  377. ##########
  378. ### Find items
  379. echo "--> Finding folders and ignoring any folder whose name contains a period and it's content (potential packages)."
  380.  
  381.  
  382. echo "--> then finding files & generating list of MD5 checksums for file content."
  383.  
  384.  
  385. find "${MainFolder}" -type d \
  386.     \! \( -name "*.*" -o -name "iPhoto Library" -o -name "iTunes" \) \
  387.     \! \( -path "*/*.*/*" -o -path "*/iPhoto Library/*" -o -path "*/iTunes/*" \
  388.           -o -path "${saveFolder}" -o -path "${saveFolder}/*" \) \
  389. | (
  390.    
  391. while read folder
  392. do
  393.  
  394.     [ "${veryVerbose}" = "Yes" ] \
  395.     && echo "folder=${folder};"  
  396.    
  397.     # Perform a 'find' within each of the folders for files in that folder
  398.     # (and not in subdirectories) Skip hidden files.
  399.     find "${folder}" -maxdepth 1 -type f \! -name ".*"  \
  400.     | (
  401.            
  402.         while read theFilePath
  403.         do
  404.             # Get an MD5 checksum for each file's combined content of both
  405.             # data and resource forks              
  406.             fileCheckSum=$( cat "${theFilePath}" "${theFilePath}/rsrc" | md5 )
  407.             echo " ${fileCheckSum}  ${theFilePath}"
  408.             echo "${fileCheckSum}${tab}f${tab}${theFilePath}" \
  409.                 >> "${saveFolder}/Index.txt"
  410.         done
  411.       )
  412. done
  413. )
  414.  
  415. Show_Time
  416.  
  417. echo "--> Finding and processing potential packages/bundles."
  418. echo "--> Note; we look for a period in the base filename which" \
  419.     "may not be acurate in all cases."
  420. # Find folders within $MainFolder which are possible packages and bundles
  421. find "${MainFolder}" -type d \
  422.   \( -iname "*.*" -o -iname "iPhoto Library" -o -iname "iTunes" \) \
  423.   \! \( -name ".*" -o -ipath "*/*.*/*" -o -ipath "*/iPhoto Library/*" \
  424.         -o -ipath "*/iTunes/*" \) \
  425. | (
  426.     while read folder
  427.     do
  428.  
  429.         fileCheckSum=$( find "${folder}" -type f \! -name ".DS_Store" \
  430.             -exec  cat '{}' '{}/rsrc' \; | md5 )
  431.  
  432.         echo "${fileCheckSum}  ${folder}"
  433.         echo "${fileCheckSum}${tab}d${tab}${folder}" >> "${saveFolder}/Index.txt"
  434.  
  435.     done
  436. )  
  437.  
  438. ######### ;;;;;;;;
  439. echo
  440. Show_Time
  441.  
  442. echo "--> Sorting list of files and potential bundles by checksum then"
  443. echo "    Compare checksums."
  444. sort -t "${tab}"  "${saveFolder}/Index.txt" |
  445.     (
  446.         declare previousCheckSum=""
  447.        
  448.         declare -i trashCount=0
  449.        
  450.         # Process both files and application bundles.
  451.         while read theData
  452.         do
  453.             checkSum="${theData:0:32}"
  454.             fileType="${theData:33:1}"
  455.             fileName="${theData:35}"
  456.            
  457.             [ "${veryVerbose}" = "Yes" ] \
  458.                 && echo "${checkSum} ${fileName};"
  459.                
  460.             if [ "${checkSum}" = "${previousCheckSum}" ] ; then
  461.                 # Duplicate file. Move current file to trash.
  462.            
  463.                 [ "${verbose}" = "Yes" ] \
  464.                     && echo -n " ="
  465.                    
  466.                 # Make up trash name.
  467.                 # Base name on path name so we can remember
  468.                 # where file came from
  469.                 trashFileName="${fileName}"
  470.                 case "${whereIsTrash}" in
  471.                 u ) trashFileName="${trashFileName:7}"
  472.                     trashFileName="${trashFileName#*/}" # chop user id
  473.                     ;;
  474.                 v)  trashFileName="${trashFileName:9}"
  475.                     ;;
  476.                 * ) echo "<><><><> Serious error. whereIsTrash=${whereIsTrash};"
  477.                 esac
  478.                
  479.                 trashFileName=$(echo -n "${trashFileName}" | tr "/" "~" )
  480.                 trashFileName="${trashFolder}/${trashFileName}"
  481.                
  482.                 # don't let a directory be copyied into another directory.
  483.                 # Happens with applications.
  484.                 # Might as well avoid files too.
  485.                 [ ! -e "${trashFileName}" ] \
  486.                     &&  mv -n "${fileName}" "${trashFileName}"
  487.                
  488.                 if [ -e "${fileName}" ] ; then
  489.                     # Move didn't work.
  490.                     myRandom=$RANDOM
  491.                     trashFileName="${trashFileName}~$(date '+%Y-%m-%d_%H.%M')~${myRandom}"
  492.                     mv -n "${fileName}" "${trashFileName}"
  493.                    
  494.                     if [ -e "${fileName}" ] ; then
  495.                         # Odd , second move didn't work.
  496.                         echo
  497.                         echo "big time error "
  498.                         echo "<><> fileName=${fileName};" \
  499.                             "myRandom=${myRandom}" \
  500.                             "trashFileName=${trashFileName};"
  501.                         echo
  502.                     else
  503.                         # Ok, moved file to trash
  504.                         echoTrashInfo
  505.                     fi
  506.                 else
  507.                     # Ok, moved file to trash
  508.                     echoTrashInfo
  509.                 fi
  510.                                    
  511.             else
  512.                 # Output data for next step.
  513.                 # Mac OS X hfs+ defaults to case independent names, so
  514.                 # sort on lower case.
  515.                 # ie A folder may not contain the names abc & Abc.
  516.                 lowerBaseName=$( echo -n "${fileName##*/}" | \
  517.                     tr '[:upper:]' '[:lower:]' )
  518.                 echo "${lowerBaseName}${tab}${fileName}" \
  519.                     >>"${saveFolder}/names.txt"
  520.             fi
  521.             previousCheckSum="${checkSum}"
  522.            
  523.            
  524.         done
  525.        
  526.         outLine="Total trashed files: ${trashFileCount}"
  527.        
  528.         outLine="${outLine}  Total trashed applications/bundles: ${trashDirectoryCount}"
  529.         echo  
  530.         echo "${outLine}"
  531.         echo
  532.         {
  533.             echo  
  534.             echo "${outLine}"
  535.             echo
  536.         }>> "${saveFolder}/Consolidate_Trashed_List_${runDateTime}.txt"
  537.     )
  538.  
  539.  
  540. Show_Time
  541.  
  542.  
  543.  
  544. ##########
  545. ### Compare names
  546.  
  547. echo "--> Sorting list of names."
  548.  
  549.  
  550. # Sort (by basename)
  551. sort -t "${tab}"  "${saveFolder}/names.txt" |
  552. (
  553.  
  554.     declare previousBaseName="" \
  555.             baseName
  556.    
  557.     declare -i alterCount
  558.    
  559.     let alterCount=0
  560.    
  561.     while read theData
  562.     do
  563.     echo "..${theData}"
  564.         lowerBaseName="${theData%${tab}*}" 
  565.         fileName="${theData#*${tab}}"
  566.         baseName="${fileName##*/}"
  567.        
  568.         [ "${veryVerbose}" = "Yes" ] \
  569.             && echo "${lowerBaseName}; ${baseName}; ${fileName};"
  570.            
  571.         if [ "${previousBaseName}" = "${lowerBaseName}" ] ; then
  572.        
  573.             [ "${verbose}" = "Yes" ] \
  574.                 && echo -n " ="
  575.            
  576.             # Rename files with duplicate names by appending #X prior to
  577.             # the filename extension (before the last period.)
  578.  
  579.             directoryName="${fileName%/*}"
  580.             extension="${baseName##*.}"
  581.            
  582.             # Was an extension found?
  583.             if [ "${extension}" != "${baseName}" ] ; then
  584.                 # extension found, since a period was in the data
  585.                 extension=".${extension}"
  586.                 name="${baseName%.*}"
  587.             else
  588.                 extension=""
  589.                 name="${baseName}"
  590.             fi 
  591.            
  592.             while [ "1" = "1" ] ; do    # do forever... simulate do until
  593.                
  594.                 let alterCount+=1
  595.                 actualAlteration="${alterCount}"
  596.                
  597.                 if [ ${alterCount} -gt 9999 ] ; then
  598.                     echo
  599.                     echo "================== odd: alterCount too big!!! "
  600.                     echo "previousBaseName=${previousBaseName}; baseName=${baseName}; fileName=${fileName}; "
  601.                     echo "================== odd: alterCount too big!!! "
  602.                     echo
  603.                     actualAlteration="${alterCount}${RANDOM}"
  604.                     break
  605.                 fi
  606.                
  607.                 # Manually implement do until.
  608.                 # If file doesn't exist, break. Unused name found.
  609.                 [ ! -e "${directoryName}/${name} #${actualAlteration}${extension}" ] \
  610.                     && break
  611.                
  612.             done
  613.            
  614.             # rename
  615.             newName="${directoryName}/${name} #${actualAlteration}${extension}"
  616.            
  617.             mv -n "${fileName}" "${newName}"
  618.             if [ -e "${fileName}" ] ; then
  619.                 # Odd , rename didn't work.
  620.                 echo
  621.                 echo "another big time error "
  622.                 echo "<><><> fileName=${fileName};" \
  623.                     "newName=${newName}"
  624.                 echo
  625.             else
  626.                 # all went well with rename
  627.                 echo " +${newName}"
  628.             fi
  629.            
  630.            
  631.         else
  632.             let alterCount=0   
  633.            
  634.         fi
  635.        
  636.         previousBaseName="${lowerBaseName}"
  637.    
  638.     done
  639.        
  640. )
  641.  
  642. Show_Time
  643.  
  644. ##########
  645. ### Moving items to top-level
  646. if [ "${MoveFiles}" = "Yes" ] ; then
  647.     echo "--> Finding possible packages/bundles and moving them to the top-level."
  648.     find "${MainFolder}" -mindepth 1 -type d \
  649.     \( -iname "*.*" -o -iname "iPhoto Library" -o -iname "iTunes" \) \
  650.     \! \( -name ".*" -o -ipath "*/*.*/*" -o -ipath "*/iPhoto Library/*" \
  651.     -o -ipath "*/iTunes/*"  \)  \
  652.         -exec mv -n '{}' "${MainFolder}" \;
  653.  
  654.     echo "--> Finding files and moving them to the top-level."
  655.     folders=( $(find "${MainFolder}" -mindepth 1 -type d \
  656.     \! \( -name "*.*" -o -name "iPhoto Library" -o -name "iTunes" \) \
  657.     \! \( -path "*/*.*/*" -o -path "*/iPhoto Library/*" -o -path "*/iTunes/*" \
  658.     -o -path "${saveFolder}" -o -path "${saveFolder}/*"  \) ) )
  659.  
  660.     # Perform a 'find' within each of the folders for files in that folder
  661.     # (and not in subdirectories)
  662.     for folder in ${folders[*]} ; do
  663.     find "${folder}" -maxdepth 1 -type f \! -name ".*"  -exec mv -n '{}' "${MainFolder}" \;
  664.     done
  665. fi
  666.  
  667. echo "--> Deleting empty subfolders. (This only deletes folders which are completely empty.)"
  668.  
  669. find -d "${MainFolder}" -type d -empty -delete
  670.  
  671.  
  672. ##########
  673. ### Regroup map files into their own folders
  674. if [ "${RegroupMapFiles}" = "Yes" ] ; then
  675.     echo "--> Finding map file groups in top-level and regrouping them to their own folders in the top-level."
  676.  
  677.     # deal with .frq first, .frq indicates group with differing filename end prior to .shp
  678.     Maps=( $( find "${MainFolder}" -maxdepth 1 -iname "*.frq" ) )
  679.     for Map in ${Maps[*]} ; do
  680.         [ ! -e "${Map}" ] && continue
  681.         [ "${Map}" = "" ] && continue
  682.         fullfilename=$( basename "${Map}" )
  683.         filename="${fullfilename%.*}"
  684.         if [ ! -e "${saveFolder}/${filename}.map" ] ; then
  685.             mkdir "${saveFolder}/${filename}.map"
  686.             find "${MainFolder}" -maxdepth 1 -iname "${filename}*.*" -type f \
  687.                 -exec mv -n '{}' "${saveFolder}/${filename}.map" \;
  688.         fi
  689.     done
  690.  
  691.     Maps=( $( find "${MainFolder}" -maxdepth 1 -iname "*.shp" ) )
  692.     for Map in ${Maps[*]} ; do
  693.         [ ! -e "${Map}" ] && continue
  694.         [ "${Map}" = "" ] && continue
  695.         fullfilename=$( basename "${Map}" )
  696.         filename="${fullfilename%.*}"
  697.         if [ ! -e "${saveFolder}/${filename}.map" ] ; then
  698.             mkdir "${saveFolder}/${filename}.map"
  699.             find "${MainFolder}" -maxdepth 1 -iname "${filename}.*" -type f \
  700.                 -exec -n mv '{}' "${saveFolder}/${filename}.map" \;
  701.         fi
  702.     done
  703. fi
  704.  
  705. Show_Time
  706. echo
  707.  
  708. if [ "${veryVerbose}" = "Yes" ]  ; then
  709.     echo "Gathering post run debug information.  May take a moment." \
  710.         "Counting files."
  711.     fileCountAfter=$( find ${MainFolder} -type f \
  712.         \! \(  -path "${saveFolder}" -o -path "${saveFolder}/*" \) \
  713.         | wc -l )
  714.     trashCountAfter=$( find ${trashFolder} -type f | wc -l )
  715.     let trashDiff=trashCountAfter-trashCountBefore
  716.     let calculateFileCountAfter=fileCountAfter+trashDiff
  717.     echo
  718.     echo "Information on files and directories in folder/directory ${MainFolder}"
  719.     echo "fileCountBefore=${fileCountBefore};" \
  720.         "fileCountAfter=${fileCountAfter};"
  721.     echo
  722.     echo "trashDiff=${trashDiff};     " \
  723.         "trashCountBefore=${trashCountBefore};" \
  724.         "trashCountAfter=${trashCountAfter};"
  725.     echo
  726.     echo "===========" 
  727.     echo "calculateFileCountAfter=${calculateFileCountAfter};"
  728.     echo
  729.     if [ "${fileCountBefore}" -ne "${calculateFileCountAfter}" ] ;  then
  730.         echo "- - - - - - - -"
  731.         echo "- - - - - - - - Error: Some files have gone missing."
  732.         echo "- - - - - - - -" \
  733.             "fileCountBefore should be equal to calculateFileCountAfter"
  734.         echo "- - - - - - - - Where files deleted from the trash?"
  735.         echo "- - - - - - - -"
  736.     fi
  737.    
  738. fi
  739. echo "DONE."
  740. echo "NOTE: Invisible files and files with unresolved name conflicts may be left within any remaining subfolders!"
  741. echo
  742. echo "${savedCommandName} script revised $(GetFileInfo -m $0)"
  743. echo
  744. echo "Bye from ${bigVersion}"
  745. echo
  746.  
  747.  
  748. exit 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement