1 votos

Búsqueda y cambio de nombre de Etiquetado Duplicados

Inadvertidamente formato de una Máquina del Tiempo de copia de seguridad de disco duro externo. Yo era capaz de recuperar muchos de los archivos, pero no los nombres de los archivos.

Todos los archivos recuperados tienen nombres genéricos como "file01010101.doc", que no es útil. Con el fin de saber cuáles son los archivos duplicados, necesito comparar los archivos recuperados los originales que tengo en mi máquina, y cambian en consecuencia. A continuación, todos los archivos que todavía tienen un nombre genérico, que debe ser única y no un duplicado.

Pregunta: ¿Cómo puedo hacer esto automáticamente? Hay un programa, script de bash, o acción de Automator que puede hacer de archivos duplicados, encontrar y cambiar el nombre? Hay casi 500.000 archivos, así que hacer esto manualmente, no es práctico.

3voto

user3439894 Puntos 5883

En esta situación, el cambio de nombre de los archivos no es el camino a seguir!

Como se dijo en el OP, "Hay casi 500.000 archivos, así que hacer esto manualmente, no es práctico.", y como mencione en mi comentario a la OP "me gustaría recomendar Gemini 2 que se puede descargar una copia gratis y ejecutarlo para ver qué encuentra. Si te gusta los resultados que usted puede considerar la compra de la misma."... Pero realmente no aclarar el motivo por el que he mencionado una aplicación que detecta y elimina duplicados.

1. Hacer una nueva y actual de la Máquina del Tiempo de copia de seguridad de la por ejemplo, Macintosh HD.
2. Utilice por ejemplo, Gemini 2 para eliminar todos los duplicados de los archivos recuperados.

Qué, eliminar todos los duplicados!? ... , con una Máquina del Tiempo de copia de seguridad de la por ejemplo, Macintosh HD, ¿por qué usted necesita para mantener los duplicados!? No, los que ya han nombrado correctamente los duplicados y copias modificadas según corresponda, de los archivos en el disco duro de Macintosh en la Máquina del Tiempo de copia de seguridad. Por lo tanto, ¿tiene realmente sentido perder el tiempo para cambiar el nombre de los duplicados de los archivos recuperados? Yo digo que No!

Ahora los archivos que permanecen en los archivos recuperados son únicos y usted puede decidir a partir de ahí cómo desea proceder. Sin duda va a tener un número mucho menor de archivos para decidir si desea o no que para mantenerlos, pero no será una tarea fácil para cambiar el nombre a un nombre significativo, ya que después de todo son únicos y no tienen un nombre significativo.

Los archivos que quedan de los archivos recuperados se puede dividir en dos grupos, OS/Aplicaciones y Datos de Usuario, el último de los cuales tiene más importancia que el primero. Debería ser relativamente fácil para crear los dos grupos y deshacerse de el OS/Apps grupo como la mayoría de los archivos serán mayores que el sistema operativo actual y de ningún valor real. Los Datos de Usuario de archivos, algunos pueden ser archivos eliminados desde el disco duro de Macintosh a lo largo del tiempo y a los otros, puede ser modificado copias de los archivos eliminados y modificados copias de los archivos actuales antes del percance. Estos son los que te quieren retener para buscar a través de como sea necesario.

La cosa más importante en esta situación es tener una Máquina del Tiempo de copia de seguridad de la por ejemplo, Macintosh HD, y el aislamiento de los únicos Datos de Usuario de los archivos dentro de los archivos recuperados, y es realmente el único punto de tamizar a través de los archivos recuperados! No andar por ahí perdiendo el tiempo cambio de nombre de los archivos que ya tienes en tanto la por ejemplo, Macintosh HD y la Máquina del Tiempo de copia de seguridad.


Tenga en cuenta que soy un usuario con licencia de la Gemini 2 app, pero no tienen ninguna otra afiliación con el desarrollador de MacPaw.

1voto

wch1zpink Puntos 11

Aquí es una solución que he probado varias veces y parece que funciona. Estoy seguro de que alguien con más experiencia puede ofrecer una solución que es mucho más rápido que el mío, pero hasta ahora este es el mejor que puede venir para arriba con.

Yo sugiero hacer una copia de su "recuperado" de los archivos con el genérico de nomenclatura de archivos. Entonces yo tendría que ejecutar el siguiente código en su copia de archivos.

Este AppleScript código me funciona con la última versión de macOS Mojave.

Simplemente pegar este AppleScript código en el Editor de secuencias de Comandos.aplicación y se puede ejecutar el código desde allí.

set genericFolder to (choose folder with prompt "Choose The Parent Folder Containing The Files To Be Renamed")
set sourceFolder to (choose folder with prompt "Choose The Parent Folder Containing The Files With Proper Names")

tell application "Finder"
    set genericFiles to files of entire contents of genericFolder as alias list
    set sourceFiles to files of entire contents of sourceFolder as alias list
end tell

repeat with genericFile in genericFiles
    repeat with sourceFile in sourceFiles
        try
            set isIdentical to (last word of (do shell script "diff -s " & quoted form of POSIX path of genericFile & " " & quoted form of POSIX path of sourceFile) is "identical") as boolean
            if isIdentical is true then
                tell application "System Events" to set name of genericFile to name of sourceFile
            end if
        end try
    end repeat
end repeat

Esta imagen es la estructura de carpetas y archivos antes de ejecutar el código. Los archivos de origen están en la imagen de izquierda y de los archivos a renombrar están a la derecha de la imagen. Tomar nota de que la carpeta y el archivo de las estructuras son diferentes en ambas imágenes.

enter image description here

La imagen siguiente es el resultado después de ejecutar el código

enter image description here

Esta solución se ha probado con sólo 38 archivos con nombres genéricos. En mi sistema se tomó 1 minuto y 33 segundos para el proceso y el nombre de los archivos en consecuencia. Sin hacer ningún matemáticas, si usted está tratando de proceso de 500.000 archivos con este código, usted podría estar buscando en la mejor parte de un día completo para que el proceso se complete. Puede que desee considerar la posibilidad de romper el proceso para el procesamiento de un par de carpetas en el tiempo, en lugar de la plena carga de la madre de todos a la vez.

Sin embargo, si sólo está buscando para cambiar el nombre de los archivos con la extensión de nombre ".doc" , puede sustituir este código de arriba...

tell application "Finder"
    set genericFiles to files of entire contents of genericFolder as alias list
    set sourceFiles to files of entire contents of sourceFolder as alias list
end tell

Con este código, que hará que el proceso sea mucho más rápido.

tell application "Finder"
    set genericFiles to ((files of entire contents of genericFolder) whose name extension is "doc") as alias list
    set sourceFiles to ((files of entire contents of sourceFolder) whose name extension is "doc") as alias list
end tell

Usted también puede tener el código de proceso sólo los archivos con extensiones de nombre de definir, como en el siguiente ejemplo.

set nameExtensions to {"doc", "pdf"}

tell application "Finder"
    set genericFiles to ((files of entire contents of genericFolder) whose name extension is in nameExtensions) as alias list
    set sourceFiles to ((files of entire contents of sourceFolder) whose name extension is in nameExtensions) as alias list
end tell

0voto

Kerry Puntos 100

Recomiendo un total de copia de seguridad de todos sus datos antes de continuar. Después de eso, crear una nueva cuenta y jugar alrededor de la nueva cuenta.

"Avanzadas Bash-Scripting Guide" cubre todo con numerosos ejemplos. http://www.tldp.org/guides.html Es el primer manual de la lista. Bash es poderoso, pero exigente.

Debe ser capaz de encontrar lo que usted necesita en el código existente. El código elimina todos los archivos duplicados moviendo sólo una copia de cada archivo único a un nuevo directorio. ( Ha sido 9 años, desde entonces he trabajado en este código. Elimina las cosas demasiado. ) El código existente crea hashes de todos los archivos en una carpeta. Compara el hash para encontrar duplicados. Usted debe ser capaz de sustituir un cambio de nombre en este momento. Se tiene el código para crear un nombre único, por alguna razón. El código contiene una amplia depuración de código para crear un registro de lo que está haciendo. Activar el registro y seguir lo que está haciendo.

#!/bin/bash

# Purpose of this script:
#
# Accurately eliminate duplicate files within a given folder. Optionally, consolidate all files
# to a common folder.  Duplicate names within the consolidate folder will be made unique.
#
# Methodology:
# Find folders within a specified top folder which are not bundles. Find files
# within each found folder [and within subfolders ]. because each folder is 
# handled individually.)
# Find potential bundles and checksum their entire content as one item.
# Get MD5 checksums for each item and save an index of all checksums and
# filepaths. Sort the index by checksum.  Compare each
# item's checksum and if a duplicate is found, move the duplicate to the trash.
# Compare each item's name and if a duplicate is found, append incrementing #X 
# to the name prior to the last period (as in "Filename #2.jpg")
# Ignore iTunes and iPhoto folders 
#
# Optionally move files and potential bundles to the top-level folder
# Delete .DS_Store, .FBCIndex*, and .FBCSemaphoreFile files and subsequently 
# delete empty subfolders.  Optionally regroup map files into folders based on 
# the name of .frq file if found, or .shp file
#
# This script is a partial rewrite of the code from JulieJulieJulie's Consolidate17 script.  
# See:
#   http://discussions.apple.com/message.jspa?messageID=11577992#11577992
#
# additional discussion:
#   https://discussions.apple.com/thread/2434165?start=0&tstart=0
#   https://discussions.apple.com/thread/8276669
# 
#   Copyright 2018 rccharles
#
#   GNU General Public License 
#
#   This program is free software: you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation,  version 3
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   For a copy of the GNU General Public License see 
#   <http://www.gnu.org/licenses/>.
#
copyRight="Copyright (c) 2010 & 2018 rccharles. GNU General Public License."
#
#


# debug info
export PS4='+(${BASH_SOURCE}:${LINENO}):'

## not in the tiger version of bash ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'


##########
### Functions (subroutines which can be called by name)

function helpHelpIsAllINeed () {
echo
echo "${savedCommandName##*/} [ options ] [ directory-to-compress ]"
echo
echo "options:"
echo "-h  Display quick help."
echo
echo "-m  Moving files is disabled." 
echo "-M  Move files to top level." 
echo
echo "-r  Regrouping map files is disabled." 
echo "-R  Regroup map files." 
echo
echo "-V  Display very detailed messages." 
echo
echo "example:"
echo "    ./${savedCommandName##*/} -mrV /Users/mac/cons/see"
echo
}

function Show_Time () {
let currentRunTime="$( date +%s ) - ${Seconds_since_the_epoch_start}"
let stepRunTime=currentRunTime-previousRunTime
echo "  Elapsed time in seconds since start of processing: ${currentRunTime}" \
     "   Time of this step: ${stepRunTime}"
echo
let previousRunTime=currentRunTime
}

function echoTrashInfo () {
    echo " -${trashFileName}"
    echo "${fileName} > ${trashFileName}" \
        >>"${saveFolder}/Consolidate_Trashed_List_${runDateTime}.txt"

    case "${fileType}" in
        f ) let trashFileCount+=1
            ;;
        d ) let trashDirectoryCount+=1
            ;;
        * ) Echo 
            Echo "Error --- Error in echoTrashInfo. fileName=${fileName};"
            Echo "Error --- fileType=${fileType};"
            Echo
            ;;
    esac    

}

declare     folder  \
            MainFolder  \
            MoveFiles="Question"    \
            RegroupMapFiles="Question"  \
            runDateTime=$(date '+%Y-%m-%d_%H.%M')   \
            Seconds_since_the_epoch_start   


declare -x  tab=$'\t'   \
            trashFolder \
            verbose="Yes"   \
            veryVerbose="Yes" \
            whereIsTrash


declare -i  count=0 \
            offsetMainFolder \
            currentRunTime \
            previousRunTime=0 \
            stepRunTime \
            trashDirectoryCount=0 \
            trashFileCount=0

declare -a  filePath    \
            fileName    \
            fileSum     \
            folders


savedCommandName="$0"
echo
echo "${savedCommandName} script revised $(GetFileInfo -m $0)"
echo
bigVersion="Lizard 4"

echo "=============================================================="
echo
echo "       ${bigVersion}"
echo "                    ${bigVersion}"
echo "                                 ${bigVersion}"
echo 
echo "=============================================================="
echo
echo "${copyRight}"
echo


# If the utility md5 is not present then just quit, it's needed for the checksums.
[ ! -x /sbin/md5 ] && exit 2

# Check for command-line options used when calling the script
if [ $# -gt 0 ] ; then
    while getopts "hmMrRV" Option ; do
        case "${Option}" in
        h ) helpHelpIsAllINeed
            echo "Bye for now."
            exit 7 
            ;;
        m ) echo "-m argument used on command line, moving files is disabled." 
            echo  
            MoveFiles="No" 
            ;;
        M ) echo "Moving files.  -M argument used on command line." 
            echo  
            MoveFiles="Yes" 
            ;;
        r ) echo "-r argument used on command line, regrouping map files is disabled." 
            echo
            RegroupMapFiles="No" 
            ;;
        R ) echo "Regrouping map files. -R argument used on command line." 
            echo
            RegroupMapFiles="Yes" 
            ;;
        V ) echo "Display very detailed messages. -V argument used on command line." 
            echo
            veryVerbose="Yes" 
            ;;
        * ) echo "Unknown argument among arguments $* on command line." 
            helpHelpIsAllINeed
            exit 6 
            ;;
        esac
    done
fi

# We're done with switches / options from the command line
shift $(($OPTIND - 1))

# Main folder can be declared on the command line or interactively
MainFolder="${1}"

# If the main folder doesn't exist, prompt once, then just quit if it's still not there.
if [ ! -d "${MainFolder}" ] ; then
    echo "Folder not specified. Type the path to the top-level folder or drag"
    echo "it into this Terminal window, then click back in this window and press return:"
    read MainFolder
    echo
fi

[ ! -d "${MainFolder}" ] \
    && echo "Folder not found. Was ${MainFolder}" \
    && exit 4

[ "${MainFolder}" = "/" ] \
    && echo "You must be crazy." \
    && exit 5

echo "Holding down Control-c on the keyboard will stop this script in an emergency."
echo

if [ "${MoveFiles}" = "Question" ] ; then
    echo "WARNING: allowing the script to move files could cause problems!"

    echo
    echo "Do you want to move all files and bundles to the top level at the end of the run?"
    read -n1 -p "Press 'n' to NOT move files and keep the folder structure intact; otherwise press any key. "
    if [ "${REPLY}" = "n" -o "${REPLY}" = "N" ] ; then
        MoveFiles="No"
    else
        MoveFiles="Yes"
    fi
    echo


fi

if [ "${RegroupMapFiles}" = "Question" ] ; then
    echo "Do you want to disable regrouping of map files into folders based on the .shp filename?"
    read -n1 -p "Press 'n' to NOT regroup map files; otherwise press any key. "
    if [ "${REPLY}" = "n" -o "${REPLY}" = "N" ] ; then
        RegroupMapFiles="No"
    else
        RegroupMapFiles="Yes"
    fi
    echo
fi

[ "${veryVerbose}" = "Yes" ] \
    && ulimit -a \
    && df \
    && echo

[ "${veryVerbose}" = "Yes" ] \
    && echo "MainFolder=${MainFolder};"

# get physical path 
if [ -d "$MainFolder" ]; then
    pushd $PWD
    cd "$MainFolder"
    MainFolder=$( /bin/pwd -P )
    popd
else
    # just to be sure.
    echo "You need to supply a directory name for ${MainFolder}"
    exit 8
fi  

let offsetMainFolder="${#MainFolder}"-1

# Ensure that the path is in a consistant format. i.e. no //
# drop trailing directory separator if needed
[ "${MainFolder:${offsetMainFolder}}" = "/" ] \
    && MainFolder="${MainFolder:0:${offsetMainFolder}}"

# Place all created files in one directory.
saveFolder="${MainFolder}/saved--Consolidated--Data"

# Figure out the trash folder name. Each user has his or her own trash folder.
# Each volume has a different trash folder. On the startup drive, 
# the trash folders are in the users home folder. On the other volumes, the 
# trash folder contains a folder with the user id for each user.
#
# This isn't perfect.  
if [ $( echo -n "${MainFolder:0:7}" | tr '[:upper:]' '[:lower:]' ) \
        = "/users/" ] ; then
    whereIsTrash="u"
    trashFolder="${HOME}/.Trash"
elif [  $( echo -n "${MainFolder:0:9}" | tr '[:upper:]' '[:lower:]' ) \
        = "/volumes/" ] ; then
    whereIsTrash="v"
    diskName="${MainFolder:9}"
    diskName="${diskName%%/*}"
    trashFolder="/Volumes/${diskName}/.Trashes"
    if [ ! -d ${trashFolder} ] ; then
        # Needs work.  Should be ok, since folder is created when formated.
        Echo "Creating trash folder. ${trashFolder};" 
        saveUmask=$( umask )
        mkdir ${trashFolder} 
        umask ${saveUmask}
    fi
    currentId=$( id -ru )
    trashFolder="${trashFolder}/${currentId}"
    if [ ! -d ${trashFolder} ] ; then
        Echo "Creating user's individual trash folder. ${trashFolder};"
        saveUmask=$( umask )
        umask 077
        mkdir ${trashFolder} 
        umask ${saveUmask} 
    fi
else
    echo "Not sure where main folder resides. defulat to ~/.Trash"
    whereIsTrash="u"
    trashFolder="${HOME}/.Trash"
fi


[ "${veryVerbose}" = "Yes" ] \
    && echo "MainFolder=${MainFolder};" \
    && echo "saveFolder=${saveFolder};" \
    && echo "trashFolder=${trashFolder};"



[ ! -d "${saveFolder}" ] \
    && mkdir "${saveFolder}"

#Housekeeping for Index files.

# If the index archive file does not exist, 
# create it so that it will be there for sorting and merging later
[ ! -e "${saveFolder}/Index_Archive.txt" ] \
    && touch "${saveFolder}/Index_Archive.txt"

# If the index file exists, archive it and be sure to delete the index.
if [ -e "${saveFolder}/Index.txt" ] ; then
    echo "----------------------------" >> "${saveFolder}/Index_Archive.txt" 
    cat "${saveFolder}/Index.txt" >> "${saveFolder}/Index_Archive.txt" 
    rm "${saveFolder}/Index.txt"
fi

touch "${saveFolder}/Index.txt"

# In case of a crash, clean up from previous run. 
[ -e "${saveFolder}/names.txt" ] \
    && rm "${saveFolder}/names.txt"

touch "${saveFolder}/names.txt"

# Ensure that the trashed list file will exist even if no files were trashed
[ ! -e "${saveFolder}/Consolidate_Trashed_List_${runDateTime}.txt" ] \
    && touch "${saveFolder}/Consolidate_Trashed_List_${runDateTime}.txt"

[ "${veryVerbose}" = "Yes" ] \
    && ls -l "${saveFolder}/Index.txt" \
    && ls -l "${saveFolder}/names.txt" \
    && ls -l "${saveFolder}/Consolidate_Trashed_List_${runDateTime}.txt" \
    && ls -ld "${trashFolder}" \
    && ls -ld "${trashFolder}/.." \
    && echo

echo "--> Deleting .DS_Store and .FBC files from subfolders."
find -d "${MainFolder}" -type f \( -name ".DS_Store" -o -name ".FBCIndex*" \
    -o -name ".FBCSemaphoreFile" \) -delete 


if [ "${veryVerbose}" = "Yes" ]  ; then
    echo "Gathering debug information.  May take a moment.  Counting files."
    fileCountBefore=$( find ${MainFolder} -type f \
        \! \(  -path "${saveFolder}" -o -path "${saveFolder}/*" \) \
        | wc -l )
    trashCountBefore=$( find ${trashFolder} -type f | wc -l )
fi

# Set the internal field separator to newline to preserve spaces in file paths
IFS=$'\n'

# Set the start time now that the user interaction is done
Seconds_since_the_epoch_start=$( date +%s )

##########
### Find items
echo "--> Finding folders and ignoring any folder whose name contains a period and it's content (potential packages)."


echo "--> then finding files & generating list of MD5 checksums for file content."


find "${MainFolder}" -type d \
    \! \( -name "*.*" -o -name "iPhoto Library" -o -name "iTunes" \) \
    \! \( -path "*/*.*/*" -o -path "*/iPhoto Library/*" -o -path "*/iTunes/*" \
          -o -path "${saveFolder}" -o -path "${saveFolder}/*" \) \
| (

while read folder
do

    [ "${veryVerbose}" = "Yes" ] \
    && echo "folder=${folder};"  

    # Perform a 'find' within each of the folders for files in that folder 
    # (and not in subdirectories) Skip hidden files.
    find "${folder}" -maxdepth 1 -type f \! -name ".*"  \
    | (

        while read theFilePath
        do
            # Get an MD5 checksum for each file's combined content of both
            # data and resource forks               
            fileCheckSum=$( cat "${theFilePath}" "${theFilePath}/rsrc" | md5 )
            echo " ${fileCheckSum}  ${theFilePath}" 
            echo "${fileCheckSum}${tab}f${tab}${theFilePath}" \
                >> "${saveFolder}/Index.txt"
        done
      )
done
)

Show_Time

echo "--> Finding and processing potential packages/bundles."
echo "--> Note; we look for a period in the base filename which" \
    "may not be acurate in all cases."
# Find folders within $MainFolder which are possible packages and bundles
find "${MainFolder}" -type d \
  \( -iname "*.*" -o -iname "iPhoto Library" -o -iname "iTunes" \) \
  \! \( -name ".*" -o -ipath "*/*.*/*" -o -ipath "*/iPhoto Library/*" \
        -o -ipath "*/iTunes/*" \) \
| ( 
    while read folder 
    do

        fileCheckSum=$( find "${folder}" -type f \! -name ".DS_Store" \
            -exec  cat '{}' '{}/rsrc' \; | md5 )

        echo "${fileCheckSum}  ${folder}" 
        echo "${fileCheckSum}${tab}d${tab}${folder}" >> "${saveFolder}/Index.txt"

    done
)   

######### ;;;;;;;;
echo
Show_Time

echo "--> Sorting list of files and potential bundles by checksum then"
echo "    Compare checksums."
sort -t "${tab}"  "${saveFolder}/Index.txt" | 
    (
        declare previousCheckSum=""

        declare -i trashCount=0

        # Process both files and application bundles.
        while read theData 
        do
            checkSum="${theData:0:32}"
            fileType="${theData:33:1}"
            fileName="${theData:35}"

            [ "${veryVerbose}" = "Yes" ] \
                && echo "${checkSum} ${fileName};"

            if [ "${checkSum}" = "${previousCheckSum}" ] ; then
                # Duplicate file. Move current file to trash.

                [ "${verbose}" = "Yes" ] \
                    && echo -n " ="

                # Make up trash name. 
                # Base name on path name so we can remember 
                # where file came from
                trashFileName="${fileName}"
                case "${whereIsTrash}" in
                u ) trashFileName="${trashFileName:7}"
                    trashFileName="${trashFileName#*/}" # chop user id
                    ;;
                v)  trashFileName="${trashFileName:9}"
                    ;;
                * ) echo "<><><><> Serious error. whereIsTrash=${whereIsTrash};"
                esac

                trashFileName=$(echo -n "${trashFileName}" | tr "/" "~" )
                trashFileName="${trashFolder}/${trashFileName}"

                # don't let a directory be copyied into another directory.
                # Happens with applications. 
                # Might as well avoid files too.
                [ ! -e "${trashFileName}" ] \
                    &&  mv -n "${fileName}" "${trashFileName}"

                if [ -e "${fileName}" ] ; then 
                    # Move didn't work.
                    myRandom=$RANDOM
                    trashFileName="${trashFileName}~$(date '+%Y-%m-%d_%H.%M')~${myRandom}"
                    mv -n "${fileName}" "${trashFileName}"

                    if [ -e "${fileName}" ] ; then
                        # Odd , second move didn't work.
                        echo
                        echo "big time error "
                        echo "<><> fileName=${fileName};" \
                            "myRandom=${myRandom}" \
                            "trashFileName=${trashFileName};"
                        echo
                    else
                        # Ok, moved file to trash
                        echoTrashInfo
                    fi
                else
                    # Ok, moved file to trash
                    echoTrashInfo
                fi 

            else
                # Output data for next step.
                # Mac OS X hfs+ defaults to case independent names, so
                # sort on lower case. 
                # ie A folder may not contain the names abc & Abc.
                lowerBaseName=$( echo -n "${fileName##*/}" | \
                    tr '[:upper:]' '[:lower:]' )
                echo "${lowerBaseName}${tab}${fileName}" \
                    >>"${saveFolder}/names.txt"
            fi
            previousCheckSum="${checkSum}"


        done

        outLine="Total trashed files: ${trashFileCount}"

        outLine="${outLine}  Total trashed applications/bundles: ${trashDirectoryCount}"
        echo  
        echo "${outLine}"
        echo
        {
            echo  
            echo "${outLine}"
            echo
        }>> "${saveFolder}/Consolidate_Trashed_List_${runDateTime}.txt"
    )


Show_Time



##########
### Compare names

echo "--> Sorting list of names."


# Sort (by basename) 
sort -t "${tab}"  "${saveFolder}/names.txt" |
(

    declare previousBaseName="" \
            baseName

    declare -i alterCount

    let alterCount=0

    while read theData 
    do
    echo "..${theData}"
        lowerBaseName="${theData%${tab}*}"  
        fileName="${theData#*${tab}}"
        baseName="${fileName##*/}"

        [ "${veryVerbose}" = "Yes" ] \
            && echo "${lowerBaseName}; ${baseName}; ${fileName};"

        if [ "${previousBaseName}" = "${lowerBaseName}" ] ; then

            [ "${verbose}" = "Yes" ] \
                && echo -n " ="

            # Rename files with duplicate names by appending #X prior to 
            # the filename extension (before the last period.)

            directoryName="${fileName%/*}"
            extension="${baseName##*.}" 

            # Was an extension found?
            if [ "${extension}" != "${baseName}" ] ; then
                # extension found, since a period was in the data
                extension=".${extension}"
                name="${baseName%.*}"
            else
                extension=""
                name="${baseName}"
            fi  

            while [ "1" = "1" ] ; do    # do forever... simulate do until

                let alterCount+=1
                actualAlteration="${alterCount}"

                if [ ${alterCount} -gt 9999 ] ; then
                    echo 
                    echo "================== odd: alterCount too big!!! "
                    echo "previousBaseName=${previousBaseName}; baseName=${baseName}; fileName=${fileName}; "
                    echo "================== odd: alterCount too big!!! "
                    echo
                    actualAlteration="${alterCount}${RANDOM}"
                    break
                fi

                # Manually implement do until. 
                # If file doesn't exist, break. Unused name found. 
                [ ! -e "${directoryName}/${name} #${actualAlteration}${extension}" ] \
                    && break

            done

            # rename
            newName="${directoryName}/${name} #${actualAlteration}${extension}"

            mv -n "${fileName}" "${newName}"
            if [ -e "${fileName}" ] ; then
                # Odd , rename didn't work.
                echo
                echo "another big time error "
                echo "<><><> fileName=${fileName};" \
                    "newName=${newName}" 
                echo
            else
                # all went well with rename
                echo " +${newName}" 
            fi


        else
            let alterCount=0    

        fi

        previousBaseName="${lowerBaseName}"

    done

)

Show_Time

##########
### Moving items to top-level
if [ "${MoveFiles}" = "Yes" ] ; then
    echo "--> Finding possible packages/bundles and moving them to the top-level."
    find "${MainFolder}" -mindepth 1 -type d \
    \( -iname "*.*" -o -iname "iPhoto Library" -o -iname "iTunes" \) \
    \! \( -name ".*" -o -ipath "*/*.*/*" -o -ipath "*/iPhoto Library/*" \
    -o -ipath "*/iTunes/*"  \)  \
        -exec mv -n '{}' "${MainFolder}" \; 

    echo "--> Finding files and moving them to the top-level."
    folders=( $(find "${MainFolder}" -mindepth 1 -type d \
    \! \( -name "*.*" -o -name "iPhoto Library" -o -name "iTunes" \) \
    \! \( -path "*/*.*/*" -o -path "*/iPhoto Library/*" -o -path "*/iTunes/*" \
    -o -path "${saveFolder}" -o -path "${saveFolder}/*"  \) ) )

    # Perform a 'find' within each of the folders for files in that folder 
    # (and not in subdirectories)
    for folder in ${folders[*]} ; do
    find "${folder}" -maxdepth 1 -type f \! -name ".*"  -exec mv -n '{}' "${MainFolder}" \;
    done
fi

echo "--> Deleting empty subfolders. (This only deletes folders which are completely empty.)"

find -d "${MainFolder}" -type d -empty -delete 


##########
### Regroup map files into their own folders
if [ "${RegroupMapFiles}" = "Yes" ] ; then
    echo "--> Finding map file groups in top-level and regrouping them to their own folders in the top-level."

    # deal with .frq first, .frq indicates group with differing filename end prior to .shp
    Maps=( $( find "${MainFolder}" -maxdepth 1 -iname "*.frq" ) )
    for Map in ${Maps[*]} ; do
        [ ! -e "${Map}" ] && continue
        [ "${Map}" = "" ] && continue
        fullfilename=$( basename "${Map}" )
        filename="${fullfilename%.*}"
        if [ ! -e "${saveFolder}/${filename}.map" ] ; then
            mkdir "${saveFolder}/${filename}.map"
            find "${MainFolder}" -maxdepth 1 -iname "${filename}*.*" -type f \
                -exec mv -n '{}' "${saveFolder}/${filename}.map" \;
        fi
    done

    Maps=( $( find "${MainFolder}" -maxdepth 1 -iname "*.shp" ) )
    for Map in ${Maps[*]} ; do
        [ ! -e "${Map}" ] && continue
        [ "${Map}" = "" ] && continue
        fullfilename=$( basename "${Map}" )
        filename="${fullfilename%.*}"
        if [ ! -e "${saveFolder}/${filename}.map" ] ; then
            mkdir "${saveFolder}/${filename}.map"
            find "${MainFolder}" -maxdepth 1 -iname "${filename}.*" -type f \
                -exec -n mv '{}' "${saveFolder}/${filename}.map" \;
        fi
    done
fi

Show_Time
echo

if [ "${veryVerbose}" = "Yes" ]  ; then
    echo "Gathering post run debug information.  May take a moment." \
        "Counting files."
    fileCountAfter=$( find ${MainFolder} -type f \
        \! \(  -path "${saveFolder}" -o -path "${saveFolder}/*" \) \
        | wc -l )
    trashCountAfter=$( find ${trashFolder} -type f | wc -l )
    let trashDiff=trashCountAfter-trashCountBefore
    let calculateFileCountAfter=fileCountAfter+trashDiff
    echo
    echo "Information on files and directories in folder/directory ${MainFolder}"
    echo "fileCountBefore=${fileCountBefore};" \
        "fileCountAfter=${fileCountAfter};" 
    echo
    echo "trashDiff=${trashDiff};     " \
        "trashCountBefore=${trashCountBefore};" \
        "trashCountAfter=${trashCountAfter};"
    echo
    echo "==========="  
    echo "calculateFileCountAfter=${calculateFileCountAfter};"
    echo
    if [ "${fileCountBefore}" -ne "${calculateFileCountAfter}" ] ;  then
        echo "- - - - - - - -"
        echo "- - - - - - - - Error: Some files have gone missing."
        echo "- - - - - - - -" \
            "fileCountBefore should be equal to calculateFileCountAfter"
        echo "- - - - - - - - Where files deleted from the trash?"
        echo "- - - - - - - -"
    fi

fi
echo "DONE."
echo "NOTE: Invisible files and files with unresolved name conflicts may be left within any remaining subfolders!"
echo
echo "${savedCommandName} script revised $(GetFileInfo -m $0)"
echo 
echo "Bye from ${bigVersion}"
echo


exit 0

Aquí es un ejemplo de la salida:

https://pastebin.com/zVWRDA9E

referencias adicionales.

Esta es una secuencia parcial de reescritura del código de JulieJulieJulie del Consolidate17 secuencia de comandos.
Ver:

http://discussions.apple.com/message.jspa?messageID=11577992#11577992

discusión adicional:

https://discussions.apple.com/thread/2434165?start=0&tstart=0

https://discussions.apple.com/thread/8276669

AppleAyuda.com

AppleAyuda es una comunidad de usuarios de los productos de Apple en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X