Apple Script: How to copy files that are on a list

Discussion in 'Mac Programming' started by DavidJones47, Nov 2, 2011.

  1. macrumors newbie

    Joined:
    Nov 2, 2011
    #1
    Hello,

    This is my first post on these forums and like many it is a question. I am editing a tutorial that is composed of a ton of video clips. The only problem is that the videos I need are mixed with videos from other projects (yeah it sucks, I know but its not my fault). Anyway, I have a list of the file names that I need to be moved to a new folder. I found this script online but it's not working. Can someone help me or post the script I should be using, I would really appreciate it seeing how I know nothing about this stuff.


    duplicate (files of folder ":Users:happymonkey:Desktop:Videoproject:Images" whose name is in paragraphs of (read (choose file))) to folder ":Users:happymonkey:Desktop:Videoproject:Images:Chapter 1"

    Thanks
     
  2. macrumors member

    Joined:
    Aug 28, 2008
    #2
    in bash/terminal

    Code:
    target="target/path"
    destination="destination/path"
    
    fnames=$(cat list_of_filenames)
    for i in $fnames; do
      echo "copying $i"
      cp ${target}/${i} ${destination}/
    done
    echo "done"
    
     
  3. macrumors 6502

    Joined:
    May 29, 2011
    Location:
    Littleton, Colorado, USA
    #3
    I am going to guess that your posted code is inside a Finder tell statement, in which case you need to use the complete file path, which includes the disk name.
     
  4. thread starter macrumors newbie

    Joined:
    Nov 2, 2011
    #4
    RedMenace, How do i find the complete disk name?

    Sero, If I were to use this would I make it into a text file and save it as .sh? Also where to I put the list of files (in "cat list_of_filenames")?

    Thanks for the responses
     
  5. macrumors 6502

    Joined:
    May 29, 2011
    Location:
    Littleton, Colorado, USA
    #5
    That would just be the name of your disk. For example, instead of
    Code:
    folder ":Users:happymonkey:Desktop:Videoproject:Images"
    it would be
    Code:
    folder "MacintoshHD:Users:happymonkey:Desktop:Videoproject:Images"
    ...or whatever the name of your disk is.
     
  6. DavidJones47, Nov 3, 2011
    Last edited: Nov 3, 2011

    thread starter macrumors newbie

    Joined:
    Nov 2, 2011
    #6
    I think I almost got it, can someone tell me what is going on here and how to fix it.

    My code is:

    Code:
    set folderA to "Macintosh HD/Users/happymonkey/Desktop/Videoproject/Images"
    set folderB to "Macintosh HD/Users/happymonkey/Desktop/Videoproject/Chapter 1"
    
    tell application "Finder"
    	
    	copy (file in folderA whose name is word in (read (choose file))) to folderB
    	
    end tell
    The file list looks like:

    Code:
    file1.mov
    file2.mov
    file3.mov
    I get the error:

    Code:
    error "Can’t get file of \"Macintosh HD/Users/happymonkey/Desktop/Videoproject/Images\"." number -1728 from file of "Macintosh HD/Users/happymonkey/Desktop/Photoproject/Images"

    ----------

    Also if I use the terminal script does it look like:


    Code:
    #!/bin/bash
    
    target="/Users/happymonkey/Desktop/Photoproject/Images/*"
    destination="/Users/happymonkey/Desktop/Photoproject/Chapter 1/*"
    
    fnames=$(cat -a /Users/happymonkey/Desktop/Photoproject/Chapter1.txt)
    
    for i in $fnames; do
      echo "copying $i"
      cp ${target}/${i} ${destination}/
    done
    echo "done"
    It appears to be working but the files wont copy.
     
  7. macrumors 6502

    Joined:
    May 29, 2011
    Location:
    Littleton, Colorado, USA
    #7
    You are mixing POSIX (slash delimited) and Finder (colon delimited) paths. When using the Finder, it doesn't know about POSIX paths, so you need to use specifiers like the ones I showed in my last post, or coerce POSIX paths. There is a decent article at satimage about using AppleScript and POSIX paths.
     
  8. thread starter macrumors newbie

    Joined:
    Nov 2, 2011
    #8
    I get the same error using colons.
     
  9. macrumors newbie

    Joined:
    Jun 4, 2008
    #9
    Finder cares about aliases, files and folders, so this should work (adding ability to copy more than one file):

    Code:
    set folderA to "Macintosh HD:Users:happymonkey:Desktop:Videoproject:Images:" as alias
    set folderB to "Macintosh HD:Users:happymonkey:Desktop:Videoproject:Chapter 1:" as alias
    
    set filesToCopy to (choose file default location folderA with multiple selections allowed) as list
    
    tell application "Finder"
    	repeat with theFile in filesToCopy
    		copy file theFile to folder folderB
    	end repeat
    end tell
    
     
  10. sero, Nov 4, 2011
    Last edited: Jun 20, 2012

    macrumors member

    Joined:
    Aug 28, 2008
    #10
    the paths were weird, plus the "a" flag you added to cat for some reason. try this - you can save it as whatever, call it in terminal by
    Code:
    bash whatever
    Code:
    #!/bin/bash
    
    target="/Users/happymonkey/Desktop/Photoproject/Images"
    destination="/Users/happymonkey/Desktop/Photoproject/Chapter\ 1"
    
    fnames=$(cat /Users/happymonkey/Desktop/Photoproject/Chapter1.txt)
    
    for i in $fnames; do
      cp ${target}/${i} ${destination}/
      echo "copying $i"
    done
    echo "done"
     
  11. DavidJones47, Nov 4, 2011
    Last edited: Nov 4, 2011

    thread starter macrumors newbie

    Joined:
    Nov 2, 2011
    #11
    Both scripts are almost doing what I want.

    The apple script is just copying the list I selected to the new folder, not the images.

    The terminal bash script is copying only the first image and not the rest.

    I feel so close to a solution, does anyone know how I would tweak these to work?

    (By, the way thanks so much for helping me, when I look at this code it's like trying to read Russian)

    ----------------------------------

    EDIT: I got the terminal script working!!!! Thanks so much you guys, you all saved me possibly hundreds of hours of doing the repetitive task of copying these manually!!! THANKS!

    Go Programming!!!
     
  12. macrumors newbie

    Joined:
    Apr 10, 2012
    #12
    AppleScript Copy Command

    You are really close,

    In AppleScript, the copy command just copies variables, so instead you need to issue the "duplicate" command. Just replace "copy" and it should work.
     
  13. kryten2, Apr 10, 2012
    Last edited: Jun 18, 2012

    macrumors 6502a

    Joined:
    Mar 17, 2012
    Location:
    Belgium
    #13
    Copy files based on txt file list

    Code:
    set files_source to (choose folder with prompt "Choose the source folder") as text
    set files_dest to (choose folder with prompt "Choose your destination folder for the copied files.") as alias
    set file_ref to (choose file with prompt "Select a txt file to read:" default location files_dest)
    set files_list to paragraphs of (read file_ref as «class utf8»)
    tell application "Finder"
    	set theFiles to a reference to entire contents of folder files_source
    	repeat with thisItem in theFiles
    		set theFileName to name of thisItem as text
    		if theFileName is in files_list then
    			try
    				-- or move thisItem to files_dest if you want to move it
    				duplicate thisItem to files_dest
    			on error
    				display dialog "Duplicate files named " & theFileName & ". Overwrite or skip?" buttons {"Cancel", "Overwrite", "Skip"} with icon caution
    				if button returned of the result is "Overwrite" then
    					duplicate thisItem to files_dest with replacing
    				end if
    			end try
    		end if
    	end repeat
    end tell
    
     
  14. macrumors newbie

    Joined:
    Apr 20, 2012
    #14
    How did you get the terminal script to work. I am trying to do the same thing and can't figure it out? It is driving me crazy!
     
  15. macrumors 6502a

    Joined:
    Mar 17, 2012
    Location:
    Belgium
    #15
    Debug your script. Change this line :

    Code:
    #!/bin/bash
    into this :

    Code:
    #!/bin/bash -x
     
  16. macrumors newbie

    Joined:
    Jul 16, 2007
    #16
    Thanks!

    @kryten2: Thank you so much for providing the user-friendly script for this process. Looked all over before finding it here.
     
  17. macrumors newbie

    Joined:
    Jul 16, 2007
    #17
    Spoke too soon; The AppleScript worked well on smaller directories, but had a couple of issues on the really big one, including time and resources consumed.

    I thought I'd try the bash script, but i'm getting this error on the destination line:

    Code:
    line 4: /Users/allen/sub3gp: is a directory
    ... and of course, it's supposed to be a directory, it's the destination! The sample above that uses Chapter\ 1 as a destination seems no different apart from the space character in the folder name.

    Any idea why i'm getting this error?

    Thanks!

    Allen
     
  18. macrumors 603

    Joined:
    Aug 9, 2009
    #18
    We need to see more context than just the error message.

    See post #15, regarding #!/bin/bash -x.

    Post the output produced by running the bash script that way.

    And if you made any changes at all to the script, even if you think it's inconsequential, post your complete actual bash script.
     
  19. macrumors 6502a

    Joined:
    Mar 17, 2012
    Location:
    Belgium
    #19
    @ramatsu : I know the script is slow with big folders. For a folder with 366 files(not very big I know) the script takes 2 minutes to run whereas a shell script finishes in 15 seconds. Made a little mod to the script. By no means it is perfect but you can try it if you like. This also takes 15 seconds to run on my testfolder.

    Code:
    set files_source to (choose folder with prompt "Choose the source folder") as text
    set files_dest to (choose folder with prompt "Choose your destination folder for the copied files.") as alias
    set file_ref to (choose file with prompt "Select a txt file to read:" default location files_dest)
    set files_list to paragraphs of (read file_ref as «class utf8»)
    repeat with aParagraph in files_list
    	try
    		do shell script "cp " & quoted form of POSIX path of files_source & quoted form of aParagraph & space & quoted form of POSIX path of files_dest
    	end try
    end repeat
    
     
  20. macrumors newbie

    Joined:
    Aug 14, 2013
    Location:
    Sonora, CA
    #20
    Things they assumed you knew

    with in your script you have "cp " this is to be used as literal text. This would only work on folders that did not have an items in it that were considered folders them selves because it is not told to be recursive. To fix this you need to simple edit it to look like this "cp -r " this will work on folder with and without sub folders.

    I have been working on a similar script my self as this one and found that you can include your sh file within the applescript contents, since you have started you would simple need to export to a bundled script this allows you to add files of your own. As with mine I added all of my sh files under scripts under Resources.

    Now at the top where you define your variables you would need to add a few things that help make it easy to find the included sh files no matter where you run the final script from.

    Code:
    on run()
    set thePath to (path to me as string)
    	set myPath to POSIX path of thePath
    	set mySh to {"sh ", myPath, "Contents/Resources/Scripts/scriptName.sh"} as text
    	do shell script mkdirRemovedApps
    end run
    
    This way you don't have to keep running this as a certain user from a certain folder. with a little bit of digging you should be able to find out how to pass a variable into a bash script so you could send it the location of your list file dynamically as well. or cause applescript to prompt for target and destination and just have your list in the the target folder.

    I hope this help finds you well even though it is about a year late.
     
  21. macrumors 6502a

    Joined:
    Jun 17, 2003
    #21
    With a bash implementation you are better off putting as many filenames on a single cp command line as you can. If that is not possible (probably due to too many files) then using GNU parallel will give you faster execution.

    GNU parallel can be installed using Fink or MacPorts.

    The following script uses parallel to copy listed files:

    Code:
    #!/bin/bash
    
    source="/Users/happymonkey/Desktop/Photoproject/Images"
    destination="/Users/happymonkey/Desktop/Photoproject/Chapter\ 1"
    
    file_list="/Users/happymonkey/Desktop/Photoproject/Chapter1.txt"
    
    PWD=`pwd`
    
    cd ${source}
    parallel cp -Rp {} "${destination}" < ${file_list}
    
    cd ${PWD}
    echo "done"
     

Share This Page