Forgive me, I'm a bit of an amature.
I'm working to comply with a records request for hundreds of students. All files are named with the first 5 digits of the name being the student's ID number. I created the script below and it runs but with no results.
I would welcome any help that you guys can provide.
with timeout of 3600 seconds
tell application "Finder"
set myFiles to files of folder POSIX file "/Volumes/Storage/Records" as alias list
end tell
repeat with aFile in myFiles
tell application "System Events"
set myvalues to {"11111", "22222", "33333", "44444", "55555", "66666", "77777", "88888", "99999", "00000", "11112", "22223", "33334", "44445", "55556", "66667", "77778", "88889", "99990"}
if name of aFile contains myvalues then
copy aFile to folder POSIX file "/Volumes/Storage/Records"
end if
end tell
end repeat
end timeout
First of all, the command to copy files in terminology of Finder and System Events is duplicate.
Second of all (and the main issue) you have to check the first 5 characters not the entire name.
And third of all, it’s not quite useful to copy the files to the same place but I guess it’s only a placeholder
property IDNumbers : {"11111", "22222", "33333", "44444", "55555", "66666", "77777", "88888", "99999", "00000", "11112", "22223", "33334", "44445", "55556", "66667", "77778", "88889", "99990"}
with timeout of 3600 seconds
tell application "Finder"
set myFiles to files of folder "Storage:Records:"
repeat with aFile in myFiles
set IDPrefix to text 1 thru 5 of (get name of aFile)
if IDPrefix is in IDNumbers then
duplicate aFile to folder "Storage:Records:Destination:"
end if
end repeat
end tell
end timeout
My solution uses only the Finder because it doesn't include the invisible files and it's not needed to coerce the Finder object specifiers to alias.
If the location of the files is on an external volume, it’s easier to use the HFS path “Storage:Records” than the coercion from POSIX path POSIX file "/Volumes/Storage/Records” as alias
I suggest you to use do shell script function instead of using Finder application as it's more flexible solution. And you can find any errors in your command easily because you can debug it using the Terminal.
do shell script "<your commands here>"
For your use case you need to use a couple of commands inside do shell script: find and then cp.
I would suggest a simple bash script is a better option here. Save the following script on your Desktop as CopyFiles
#!/bin/bash
# Make a subdirectory to copy the results to
mkdir results 2>/dev/null
# Read all ids from file "ids.txt"
while read id; do
echo Processing id: $id
# Remove the word "echo" on following line to actually copy files
echo cp /Volumes/Storage/Records/${id}* results
done < ids.txt
It assumes there is a file on your Desktop called ids.txt that looks like this
11111
22222
12345
54321
Then start a Terminal, by pressing Cmd+Spacebar and typing "Terminal" and hitting "Enter".
Go to your Desktop and make the script executable with
cd Desktop
chmod +x CopyFiles
and then run it with
./CopyFiles
At the moment, it does nothing except tell you what it would do like this:
Processing id: 11111
cp /Volumes/Storage/Records/11111* results
Processing id: 22222
cp /Volumes/Storage/Records/22222* results
Processing id: 12345
cp /Volumes/Storage/Records/12345* results
Processing id: 54321
cp /Volumes/Storage/Records/54321* results
If it looks like it is doing what you want, edit the script and remove the word echo where noted and run it again.
Related
I need some help with an apple script that I can save on the computer so others can remove the ._ files from USB drives that are used for slide shows on TVs. I come from Linux so I pseudoed what I could.
usb_drives=$(ls /volumes/ | grep external) # intent
MyFlashDrive=$(prompt "Please select drive" usb_drives) # intent
dot_clean -m /Volumes/${MyFlashDrive} # mostly accurate
The AppleScript version of this would be something like the following:
tell application "System Events"
set ejactableDisks to get (displayed name of every disk whose ejectable is true)
--name of every file of home folder whose name begins with "."
end tell
set targetDiskName to choose from list ejactableDisks
tell application "System Events"
set targetDisk to first disk whose name is targetDiskName
set dotUnderscoreFiles to every file of targetDisk whose name begins with "._"
if (count of dotUnderscoreFiles) is greater than 0 then
delete dotUnderscoreFiles
end if
end tell
Of course, if you're more comfortable with unix you could write a bash routine and run it through do shell script, or just make an executable bash script.
I'm trying to create a context menu shortcut to open a file/folder in VS Code from the original item or its alias
So far I was able to create an Automator Service, which:
receives selected: files or folders
in: any application run
shell script:
open -n -b "com.microsoft.VSCode" --args "$*"
How can I change it to accept also aliases?
Symbolic links should be OK, but Finder aliases usually don't work, since most shell utilities see them as small data files and don't know how to interpret them. One solution would be to add a Run AppleScript action to look for aliases in the input and use the original item instead, for example:
Service receives selected files or folders in any application
Run AppleScript:
on run {input, parameters}
set output to {} -- this will be a list of the output items
tell application "Finder" to repeat with anItem in the input
if anItem's kind is "Alias" then
set the end of output to POSIX path of (original item of anItem as alias)
else
set the end of output to POSIX path of anItem
end if
end repeat
return output
end run
Run Shell Script, etc
I have a Automator workflow that utilizes this shell script to grab the name of the directory hosting the file running through this workflow. Later I place that directory name as comment for the file.
for f in "$#"
do
filepath=$(dirname "$f")
dirname=$(basename "$filepath")
echo "$dirname"
done
Whenever I throw multiple files at it though, the directory name gets reflected not once (as I would like to) but times however many files I dropped at it. This then later adds the same comment that many times.
How do I fix that?
EDIT:
I want to try eliminate Automator and go with Applescript + Shell alone.
How do I have the shell return the directory name? Right now it just gives me $dirname in the dialog...
on adding folder items to theWatchedFolder after receiving theDetectedItems
set dirName to do shell script "for f in '$#'
do
filepath=$(dirname '$f')
dirname=$(basename '$filepath')
echo '$dirname'
done"
display alert dirName
end adding folder items to
on adding folder items to thisFolder after receiving added_items
repeat with aFile in added_items
tell application "Finder"
set parentpath to POSIX path of (parent of (aFile) as string)
set comment of aFile to parentpath
end tell
end repeat
end adding folder items to
I would go with an Applescript droplet.
Save this code as an Application.
When you drop files onto it from a single dir or multiple, it will comment each file with it's own original dir.
Then move the file to the listed move folder.
property moveFolder : "Macintosh HD:Users:USERNAME:fooDIR:"
on open theseFiles
repeat with i from 1 to number of items in theseFiles
set this_item to item i of theseFiles
tell application "Finder"
set parentpath to POSIX path of (parent of (this_item) as string)
set comment of this_item to parentpath
end tell
end repeat
tell application "Finder"
move theseFiles to moveFolder
end tell
end open
You could use a choose command to choose where to move the files instead of hard coding but the files may not be always handed of to the droplet in a single batch even though thats how you dropped them on to it. This means the `choose dialog may display multiple times on whats seems a single run.
But the above hopefully gives you a starting place.
I'd like to expand my existing...
run script file "Macintosh HD:Users:pathTo:myScript.scpt"
to run all scripts found in a given directory. I've tried...
tell application "Finder" to set scriptsToRun to files of folder POSIX file "/Users/pathTo/" as alias list
run script file scriptsToRun
but no luck with that. Also unless necessary I don't particularly need to involve Finder in my equation. Any suggestions appreciated.
scriptsToRun is a list, so you need to repeat over the list and run each one separately. Notice I used parenthesis to ensure the code is interpreted correctly in the Finder line.
Also notice you don't need "file" in the "run script" line because the list of files is already a list of alias files... from the Finder line. You would only need the word "file" if you had a list of files in string format, then you'd use "file" before each string to make it a file specifier before running it.
Good luck.
tell application "Finder" to set scriptsToRun to (files of folder POSIX file "/Users/pathTo/") as alias list
repeat with aScript in scriptsToRun
run script aScript
end repeat
I need to zip the content of a folder (and all the subfolders) for hundreds of folders.
Is it possible to run a command that takes all the files of a specific folder (prompt), except all the files that have a .fla extension and zip this content into one zipfile?
Right now I am copying the folder, search for all the .fla-files, then select all the files inside the folder (I have the to zip the content, not the folder) and create a zip of it (takes way too long.
I know that it is possible to use Apple Script to delete and copy files. But does this also work in the above mentioned order + zipping?
Alright, so I was still kind of stuck with this issue.
I created a Bash Script, that is executed via an Applescript executable File that has only one line of code:
do shell script "/Volumes/Work/createZipFile.sh"
The Bash Script opens Applescript which lets me prompt a folder (I know, kind of silly to open AS to run a Bash Script that runs AS). The variable is then used to zip this folders content without the .fla files.
myFolder=`/usr/bin/osascript << EOT
tell application "Finder"
activate
set myfolder to choose folder with prompt "Select the Folder that you want to zip!"
end tell
return (posix path of myfolder)
EOT`
cd $myFolder
zip -r ZipMe.zip . -x ".fla"
echo "A zip File has been created"
So this script does actually work for some folder I try to zip.
But unfortunately not for every folder I chose. Sometimes (no idea why) it seems like it can not find the folder I chose with the prompt, so I starts (at least the zip-process starts running like crazy and doesn't stop) zipping my whole drive.
Any ideas what could be wrong?
In case anybody wants to use this script (which I highly doubt ;)), here is my final version of it.
#!/bin/bash
#Opens an applescript prompt window to select a folder
myFolder=`/usr/bin/osascript << EOT
tell application "Finder"
activate
set myfolder to choose folder with prompt "Select the Folder that you want to Zip!"
end tell
return (posix path of myfolder)
EOT`
# Terminate if the path is empty (canceled)
if [ -z "$myFolder" ];
then
#echo "Chose a folder!"
exit 0
else
#Change the directory to the above selected folder
cd "$myFolder"
# Creates a ZipFile with todays date of the selected folder, neglecting the after -x listed filetypes
zip -r ZipFile_`eval date +%Y_%m_%d`.zip . -x "*.fla*" "*.AppleDouble*" "*.DS_Store*"
#echo "A zip File has been created"
fi
Your first step should be to figure out what "Kind" of file the .fla is. To do this, run this script and select one of your .fla files:
tell application "Finder"
set theFile to choose file
display dialog (kind of theFile) as string
end tell
And then to get all of the files BUT that type in any folder, you can run this script (Replacing "Plain Text" with whatever type your .fla's turn out to be):
tell application "Finder"
set thePath to choose folder
set theFiles to get every file of folder thePath whose kind is not equal to "Plain Text"
end tell
from there it's just a matter of zipping. After doing some quick googling it looks like the easiest way to zip from applescript is by using do shell script, which shouldn't be that bad now that you have all the files you need in a nifty little array. If you're going for speed though, I might suggest moving this whole project over to bash. That should also simplify things quite a bit. Best of luck!