PJJPtx

Q: Automator/Applescript to Rename files when dropped in folder based on parent folder name

When a file is dropped in a folder ( ParentFolder/Folder/File.pdf )

I want to rename the file to ParentFolder_Folder_01.pdf

    --Get folder

    --Get ParentFolder

    --Check for next available number and use it.

    If ParentFolder_Folder_01.pdf exists, try _02

 

I automator, I have chosen folder action

Added 'Get selected finder items'

I have attempted to modify another sript I found here to no avail.

 

on run {input, parameters}

    tell application "Finder"

        set theFolder to input as string

        set theNameOfFolder to name of folder theFolder

        set theFiles to every file in folder theFolder

        set theFolders to every folder in folder theFolder

        my ProcessFiles(theNameOfFolder, theFiles)

        my ProcessFolders(theFolders)

    end tell

end run

 

to ProcessFolders(theFolders)

    tell application "Finder"

        repeat with thisFolder in theFolders

            set theNameOfFolder to name of thisFolder

            set theFiles to every file in thisFolder

            set theFolders to every folder in thisFolder

            my ProcessFiles(theNameOfFolder, theFiles)

            my ProcessFolders(thisFolder)

        end repeat

    end tell

end ProcessFolders

 

to ProcessFiles(NameOfOuterFolder, theFiles)

    tell application "Finder"

        repeat with thisFile in theFiles

            set theSuffix to my grabSuffixOfFile(name of thisFile)

            set name of thisFile to NameOfOuterFolder & "_" & theSuffix

        end repeat

    end tell

end ProcessFiles

 

to grabSuffixOfFile(theFile)

    set text item delimiters to "_"

    return (text item 2 of theFile)

    set text item delimiters to ""

end grabSuffixOfFile

iMac, Mac OS X (10.7.2)

Posted on Jan 8, 2012 11:25 PM

Close

Q: Automator/Applescript to Rename files when dropped in folder based on parent folder name

  • All replies
  • Helpful answers

Page 1 Next
  • by red_menace,Solvedanswer

    red_menace red_menace Jan 10, 2012 6:49 PM in response to PJJPtx
    Level 6 (15,541 points)
    Desktops
    Jan 10, 2012 6:49 PM in response to PJJPtx

    Normally it is a bad idea to do things with items that are in the attached folder (earlier OS versions will retrigger folder actions when an item is renamed, for example), and you don't need to use a Get Selected Finder Items action since the dropped items are already passed to your workflow (also note that the input items will be a list).

     

    It looks like you are trying to use multiple passes to add on the folder names, but you will have less of a headache if you build the base name and just deal with the number suffix.  If I understood your naming scheme correctly, the following script should do the trick - it isn't very fast, but should be OK for a few items at a time.

     

     

    on run {input, parameters} -- rename input Finder items (aliases) to name of containing folders

     

      set divider to "_" -- the divider character between name pieces

      set output to {} -- the result to pass on to the next action

      set counter to "01" -- start suffix at one

     

      repeat with anItem in the input -- step through each item in the input

      set anItem to contents of anItem -- dereference

      tell application "Finder" to if class of item anItem is document file then -- don't mess with folders or applications

      set {itemParent, itemExtension} to {container, name extension} of anItem

      if itemExtension is not "" then set itemExtension to "." & itemExtension

      set grandParentName to name of container of itemParent

      set parentName to name of itemParent

     

      set newName to grandParentName & divider & parentName & divider & counter

      set documentNames to my getExistingNames(itemParent)

      repeat while newName is in documentNames -- increment counter suffix as needed

                                            set counter to text -2 thru -1 of ("0" & (counter + 1))

      set newName to grandParentName & divider & parentName & divider & counter

      end repeat

     

      set name of anItem to (newName & itemExtension)

      set end of output to anItem -- alias still refers to the same file even after renaming

      end if

      end repeat

     

      return the output

    end run

     

     

    to getExistingNames(someFolder) -- get base document names (no extensions) from a folder

      set nameList to {}

     

      tell application "Finder" to repeat with aFile in (get document files of someFolder)

      set {fileName, fileExtension} to {name, name extension} of aFile

      if fileExtension is not "" then set fileExtension to "." & fileExtension

      set fileName to text 1 thru -((count fileExtension) + 1) of fileName -- just the name part

      set end of nameList to fileName

      end repeat

     

      return nameList

    end getExistingNames



  • by P8923J,

    P8923J P8923J Jan 11, 2012 7:37 AM in response to red_menace
    Level 1 (0 points)
    Jan 11, 2012 7:37 AM in response to red_menace

    You are amazing! Thank you! I am actually using this to keep my personal digital filing cabinet of PDF's in order.

    I have another script that takes scanned PDF's from an inbox, OCR's them with Finereader, appends _OCR to the filename and moves them to an OCT_Complete folder. From there, I will review them one by one and drop them into their final folders where they can be renamed. You gave me the final piece to my puzzle. Thanks!

     

    2 questions.

    1) If I have GrandParent_Parent_01.pdf, GrandParent_Parent_02.pdf, it renames them all and begins with the next number, in this case being 03. Thoughts on checking for existing matching filenames and skipping?

     

    2) Would I be better off to fire my scripts in this situation based on a time schedule, like once every night, rather than as a folder action?

  • by PJJPtx,

    PJJPtx PJJPtx Jan 11, 2012 7:41 AM in response to P8923J
    Level 1 (0 points)
    Jan 11, 2012 7:41 AM in response to P8923J

    The above comment was me. I was signed in under a different account.

  • by PJJPtx,

    PJJPtx PJJPtx Jan 11, 2012 7:44 AM in response to PJJPtx
    Level 1 (0 points)
    Jan 11, 2012 7:44 AM in response to PJJPtx

    The increment may be due to my own fault as I an currently testing this from within automator

    1. Ask for finder items, where I choose the parent folder

    2. Get folder contents.

    3. run applescript

  • by red_menace,Helpful

    red_menace red_menace Jan 11, 2012 8:26 AM in response to P8923J
    Level 6 (15,541 points)
    Desktops
    Jan 11, 2012 8:26 AM in response to P8923J

    1) I wrote the script for a folder action, so only new items dropped into a folder would be getting passed to it.  If you are doing something like getting the entire contents of a folder that may already have renamed items in it, then you can wrap the renaming part in a test statement to check if items are already renamed, for example:

     

                                  --

      set parentName to name of itemParent

     

      set newName to grandParentName & divider & parentName & divider -- base name minus suffix number

      if (name of anItem) does not start with newName then -- only rename if not already formatted

          set newName to newName & counter

          set documentNames to my getExistingNames(itemParent)

          repeat while newName is in documentNames -- increment counter suffix as needed

              set counter to text -2 thru -1 of ("0" & (counter + 1))

              set newName to grandParentName & divider & parentName & divider & counter

          end repeat

     

          set name of anItem to (newName & itemExtension)

      end if

      set end of output to anItem -- alias still refers to the same file even after renaming

                                  --

     

    2)  Since the script isn't the speediest thing around, if you wind up dropping a large number of files at one time it may take a while, so in that case the folder action route might work better.  With the above modification, it will also work by selecting files or getting the folder contents, so whatever works for your workflow.

  • by PJJPtx,

    PJJPtx PJJPtx Jan 14, 2012 11:00 PM in response to red_menace
    Level 1 (0 points)
    Jan 14, 2012 11:00 PM in response to red_menace

    here's the new code that seems to work

     

    set this_folder to (choose folder with prompt "Pick the folder containing the images to process:") as string

    set divider to "_" -- the divider character between name pieces

    set output to {} -- the result to pass on to the next action

    set counter to "01" -- start suffix at one

     

    tell application "System Events"

        set these_files to every file of folder this_folder whose name ends with "PDF"

    end tell

     

    repeat with i from 1 to the count of these_files

        set this_file to (item i of these_files as alias)

        --    set this_file to contents of this_file -- dereference

        tell application "Finder" to if class of item this_file is document file then -- don't mess with folders or applications

            set {itemParent, itemExtension} to {container, name extension} of this_file

            if itemExtension is not "" then set itemExtension to "." & itemExtension

            set grandParentName to name of container of itemParent

           

            set parentName to name of itemParent

            set newName to grandParentName & divider & parentName & divider -- base name minus suffix number

            if (name of this_file) does not start with newName then -- only rename if not already formatted

                set newName to newName & counter

                set documentNames to my getExistingNames(itemParent)

                repeat while newName is in documentNames -- increment counter suffix as needed

                    set counter to text -2 thru -1 of ("0" & (counter + 1))

                    set newName to grandParentName & divider & parentName & divider & counter

                end repeat

                set name of this_file to (newName & itemExtension)

            end if

            set end of output to this_file -- alias still refers to the same file even after renaming

        end if

    end repeat

     

    to getExistingNames(someFolder) -- get base document names (no extensions) from a folder

        set nameList to {}

        tell application "Finder" to repeat with aFile in (get document files of someFolder)

            set {fileName, fileExtension} to {name, name extension} of aFile

            if fileExtension is not "" then set fileExtension to "." & fileExtension

            set fileName to text 1 thru -((count fileExtension) + 1) of fileName -- just the name part

            set end of nameList to fileName

        end repeat

        return nameList

    end getExistingNames

     

    Now I am rename on dropping into the folder with the first script and rename non-conforming files as well. This is very helpful because I sometimes name files GrandParent_Parent_01_notes.pdf

    Now, these notes will not get overwritten.

     

    Thanks a ton!

  • by mtimmons,

    mtimmons mtimmons Jan 16, 2013 1:33 PM in response to PJJPtx
    Level 1 (0 points)
    Jan 16, 2013 1:33 PM in response to PJJPtx

    hello. Great post. I am working on a small automator-app applscript based that takes in 'droppped on' files...then prompts you to enter the new 'base name' if you will.

     

     

    I have a version working great, but am having difficulty with making the suffix counter work properly. For instance, if you had 10 files the count should be "001 ... 010" not just "01… 10". The container method as mentioned in this thread it now working in the automator "repeat with f in input" stucture. Any help would be appreciated.

     

     

    current code:

     

    on run {input, parameters}

              set theName to the text returned of (display dialog "Enter Base File Name" default answer "")

              set counter to "01"

              tell application "Finder"

     

                        repeat with f in input

                                  set theExtension to "." & name extension of f

                                  set the name of f to (theName & "_" & counter & theExtension)

                                  set counter to (counter + 1)

                        end repeat

      display dialog "Done!" buttons {"OK"} default button 1 with icon 1

     

              end tell

     

    end run

  • by twtwtw,

    twtwtw twtwtw Jan 16, 2013 1:41 PM in response to mtimmons
    Level 5 (4,935 points)
    Jan 16, 2013 1:41 PM in response to mtimmons

    to have a three digit index, change this line

     

    set counter to text -2 thru -1 of ("0" & (counter + 1))

     

    to this:

     

    set counter to text -3 thru -1 of ("00" & (counter + 1))

     

    or if you want something generic

     

    set counter to text -digits thru -1 of ("00000000000000" & (counter + 1))

     

    all this line is doing is prefixing the index with a string of zeros, then trimming off the leading zeros to make a string of the correct length.

  • by mtimmons,

    mtimmons mtimmons Jan 16, 2013 2:10 PM in response to twtwtw
    Level 1 (0 points)
    Jan 16, 2013 2:10 PM in response to twtwtw

    that works perfect for 3 digits.  the "-digits" errors on on run.

     

    What about it being dynamic? basically, always having prefixed "0".. see when you send 999 files you would get "0001 ... 0999"

     

    yeah.. 999 is a lot, but it just tried it with a gopro sequence.

  • by twtwtw,

    twtwtw twtwtw Jan 16, 2013 2:19 PM in response to mtimmons
    Level 5 (4,935 points)
    Jan 16, 2013 2:19 PM in response to mtimmons

    well that's what the 'digits' variable is for.  e.g.:

     

    set digits to 5

    set counter to 3

     

    set counter to text -digits thru -1 of ("00000000000000" & (counter + 1))

    --result "00004"

     

    so to make a dynamic version, get the number of files you're trying to convert and use the following (of course, you only need to set digits once, not every time in the loop like this, but for brevity...):

     

    -- get the string length needed based on the string length of the number of files

    set digits to (length of (numberOfFiles as text))

    set counter to text -digits thru -1 of ("00000000000000" & (counter + 1))

  • by mtimmons,

    mtimmons mtimmons Jan 16, 2013 2:56 PM in response to twtwtw
    Level 1 (0 points)
    Jan 16, 2013 2:56 PM in response to twtwtw

    ah! thank you for the tip. I coded out a count to get the amount of files and got everything working perfeclty. thanks you!

     

    final code:

     

    set theName to the text returned of (display dialog "Enter Base File Name" default answer "")

    set counter to "1"

    set numberOfFiles to "0"

     

                      tell application "Finder"

                                  repeat with f in input

                                            set numberOfFiles to numberOfFiles + 1

                                  end repeat

                                  set digits to ((length of (numberOfFiles as text)) + 1)

                                  repeat with f in input

                                                 set itemExtension to name extension of f

                             if itemExtension is not "" then set itemExtension to "." & itemExtension

     

                                                 set counter to text -digits thru -1 of ("00000000000000" & (counter))

                                                 set the name of f to (theName & "_" & counter & itemExtension)

                                                 set counter to text -digits thru -1 of ("00000000000000" & (counter + 1))

     

                                  end repeat

      display dialog "Done!" buttons {"OK"} default button 1 with icon 1


  • by twtwtw,

    twtwtw twtwtw Jan 16, 2013 3:11 PM in response to mtimmons
    Level 5 (4,935 points)
    Jan 16, 2013 3:11 PM in response to mtimmons

    Just because I noiced it, you don't need to add up the files that way.  you can replace this:

     

    set numberOfFiles to "0"

     

                      tell application "Finder"

                                  repeat with f in input

                                            set numberOfFiles to numberOfFiles + 1

                                  end repeat


    with this:

     

    set numberOfFiles to count of input

     

                       tell application "Finder"

  • by mtimmons,

    mtimmons mtimmons Jan 16, 2013 3:17 PM in response to twtwtw
    Level 1 (0 points)
    Jan 16, 2013 3:17 PM in response to twtwtw

    nice. thank you. I will clean it up.. Nice to know that for the future now..

  • by esq,

    esq esq Feb 2, 2013 1:53 PM in response to mtimmons
    Level 1 (0 points)
    Feb 2, 2013 1:53 PM in response to mtimmons

    hi!

    can you please post your final script? the one listed above is not working - where are "f" and "input" defined, the script seems to choke over these.

    thanks!

Page 1 Next