Advertisement
rccharles

Untitled

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