macosterminalapplescriptstat

Recursively get file size and file path of images in a folder, except certain subfolders


I would like to get a directory path. From there, I'd like to return the file size and filepath for designated image types within the root and subdirectories, but excluding images within subdirectories that don't contain specific words (for example: "old", "Old", "Archive"). Exclusion criteria would be non-case sensitive.

I know the command that would return the file size and filepath of a file format [extension], within a directory [DIR] as the root directory is: stat -f '%z %N' [DIR]*.[extension]

I have the (very poorly written) AppleScript code below that will grab the size and path for tif, psd, psb png and jpg.

What it doesn't do is drill into all subfolders or add in the exclusion criteria (i.e. "old" or "archive"). Could anyone help clean this code up and/or add this functionality? If it could be done with a single terminal command; even better!

tell application "Finder"
    
    set the source_folder to choose folder with prompt ¬
        "Select folder to process:"
    
    set this_item to alias (source_folder as text) as string
    
    set folder_path to quoted form of POSIX path of this_item
    
    set tif_Sizes to ""
    set psd_Sizes to ""
    set psb_Sizes to ""
    set png_Sizes to ""
    set jpg_Sizes to ""
    set all_Sizes to ""
    
    try
        
        set tif_Sizes to do shell script "stat -f '%z %N' " & folder_path & "*.tif"
        
    end try
    
    try
        
        set psd_Sizes to do shell script "stat -f '%z %N' " & folder_path & "*.psd"
        
    end try
    
    try
        
        set psb_Sizes to do shell script "stat -f '%z %N' " & folder_path & "*.psb"
        
    end try
    
    try
        
        set png_Sizes to do shell script "stat -f '%z %N' " & folder_path & "*.png"
        
    end try
    
    try
        
        set jpg_Sizes to do shell script "stat -f '%z %N' " & folder_path & "*.jpg"
        
    end try
    
    try
        
        set all_Sizes to tif_Sizes & return & psd_Sizes & return & psb_Sizes
        
    end try
    
end tell

3/30 Edit: Turns out I could do this with ExifTool after all! Just needed to add # to the -FileSize# tag to get it to report in bytes!

exiftool -i HIDDEN -ext psb -ext psd -ext png -ext tif -ext jpg -filesize# -filename -if5 '$directory !~ /old|archive/i' -r [DIR]

Solution

  • This should do the trick.

    activate
    set searchFolder to quoted form of POSIX path of (choose folder)
    
    set shellScript to "find " & searchFolder & ¬
        " -type d ! \\( -iname '*old*' -o -iname '*archive*' \\) |while read line ;do find \"$line\" -type f \\( -iname '*.psd' -o -iname '*.jpg' -o -iname '*.tif' -o -iname '*.psb' -o -iname '*.png' \\) -maxdepth 1 ;done |sort -f |tr -s '//' |while read line ;do stat -f '%z %N' \"$line\" ;done"
    
    set text item delimiters to linefeed
    set theResults to paragraphs of (do shell script shellScript) as text
    
    do shell script "printf " & quoted form of theResults & ¬
        " |cut -w -f1- > /private/tmp/Search_Results.txt"
    
    tell application "Finder" to reveal POSIX file "/private/tmp/Search_Results.txt"
    

    VERSION 2: Added option for recursive or selected folder only search

    activate
    set searchFolder to quoted form of POSIX path of ¬
        (choose folder with prompt "Select A Folder To Search In")
    
    activate
    set searchType to (choose from list {"Root Folder Only Search", "Recursive Folders Search"} ¬
        with title "Search Options" with prompt ¬
        "Search selected folder only or search all folders within the chosen folder?" OK button name ¬
        "OK" cancel button name "Cancel" without empty selection allowed) as text
    
    if searchType = "Root Folder Only Search" then
        set shellScript to "find -E " & searchFolder & ¬
            " -type f -mindepth 1 -maxdepth 1 -iregex '.*\\.(jpg|png|tif|psd|psb)' |sort -f |tr -s '//' |while read line ;do stat -f '%z %N' \"$line\"  ;done"
    else
        set shellScript to "find " & searchFolder & ¬
            " -type d ! \\( -iname '*old*' -o -iname '*archive*' \\) |while read line ;do find -E \"$line\" -type f -iregex '.*\\.(jpg|png|tif|psd|psb)' -maxdepth 1 ;done |sort -f |tr -s '//' |while read line ;do stat -f '%z %N' \"$line\" ;done"
    end if
    
    set text item delimiters to linefeed
    set theResults to paragraphs of (do shell script shellScript) as text
    
    do shell script "printf " & quoted form of theResults & ¬
        " |cut -w -f1- > /private/tmp/Search_Results.txt"
    
    tell application "Finder" to reveal POSIX file "/private/tmp/Search_Results.txt"
    

    VERSION 3: Added option for recursive or selected folder only search and option to enter the file extensions to search for.

    NOTE: This option will not allow you to exclude certain folders from the recursive search. It will either search the root folder or the root folder and all of its sub folders.

    set {leftSideOfRegex, rightSideOfRegex} to {"'.*\\.(", ")'"}
    
    set text item delimiters to "|"
    
    activate
    set searchCriteria to words of text returned of ¬
        (display dialog "Enter file extensions to be searched." & linefeed & ¬
            "(extension... followed by a comma and space)" default answer ¬
            "png, tif, psd, jpg, psb" buttons {"Cancel", "OK"} default button 2 cancel button 1) as text
    
    activate
    set searchFolder to quoted form of POSIX path of ¬
        (choose folder with prompt "Select A Folder To Search In")
    
    activate
    set searchType to (choose from list {"Root Folder Only Search", "Recursive Folders Search"} ¬
        with title "Search Options" with prompt ¬
        "Search selected folder only or search all folders within the chosen folder?" OK button name ¬
        "OK" cancel button name "Cancel" without empty selection allowed) as text
    
    if searchType = "Root Folder Only Search" then
        set shellScript to "find -E " & searchFolder & ¬
            " -type f -mindepth 1 -maxdepth 1 -iregex " & ¬
            leftSideOfRegex & searchCriteria & rightSideOfRegex & ¬
            " |sort -f |tr -s '//' |while read line ;do stat -f '%z %N' \"$line\" ;done"
    else
        set shellScript to "find -E " & searchFolder & ¬
            " -type f -mindepth 1 -iregex " & ¬
            leftSideOfRegex & searchCriteria & rightSideOfRegex & ¬
            " |sort -f |tr -s '//' |while read line ;do stat -f '%z %N' \"$line\" ;done"
    end if
    
    set text item delimiters to linefeed
    set theResults to paragraphs of (do shell script shellScript) as text
    
    do shell script "printf " & quoted form of theResults & ¬
        " |cut -w -f1- > /private/tmp/Search_Results.txt"
    
    tell application "Finder" to reveal POSIX file "/private/tmp/Search_Results.txt"