Automator/Applescript + shell script: grab parent folder name - shell

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.

Related

AppleScript - Copy All files/folders from source folder to destination folder

I'm trying to write an AppleScript that will simply copy the contents (both folders and files) from a specified source folder to a specified destination folder. At the moment my script runs but only copies one file and I can't work out how to get it to copy all files in the folder.
Here's my script:
set sourceFolder to (POSIX file "/Users/benny/Desktop/Projects/Source/Project1") as alias
set destinationFolder to (POSIX file "/Users/benny/Documents/Masters/Project1") as alias
tell application "System Events"
set availableSourceFiles to every file of sourceFolder whose visible is true
set filesOfTargetFolder to files of destinationFolder whose visible is true
end tell
-- if no more source file is available, quit this script
if (count of availableSourceFiles) = 0 then
quit
end if
set sourceFile to (first item of availableSourceFiles) as alias
-- use the Finder to copy the file
tell application "Finder"
-- duplicate the file to the target folder
duplicate sourceFile to destinationFolder
end tell
I'm assuming I need to include a for each type loop but can't get the syntax correct here. Haven't written AppleScripts in many years so trying to remember how it all works.
If the destination "Project1" folder doesn't have stuff in it already, then duplicating the folder is likely to be quicker:
tell application id "com.apple.Finder" to duplicate folder POSIX file ¬
"/Users/benny/Desktop/Projects/Source/Project1" to the folder ¬
POSIX file "/Users/benny/Documents/Masters" with replacing
However, if that's not an option, then I'd stick with your method and copy the contents of the folder across instead:
set here to POSIX file "/Users/benny/Desktop/Projects/Source/Project1"
set there to POSIX file "/Users/benny/Documents/Masters"
tell application id "com.apple.Finder" to duplicate ¬
every item in the folder here to there
Bear in mind that if there's a file or folder at any of the destinations that intended to be occupied by one of the incoming source items, Finder will throw an error. You would typically incorporate some sort of check ahead of the copy.

AppleScript newbie: trying to create a script that removes all files in a folder that has the word 'alias' in its name

I timemachined my new computer, so I can have an easier migration to my new Mac. For some reason, Time Machine decided to make an alias of every single file that is in my downloads folder (I have roughly 300 files), which annoys me to no end.
I tried to make a script that would solve my problem, but I just can't wrap my head around why this doesn't work.
try
tell application "Finder"
delete (every item of folder (path to downloads folder) whose name ends with " alias")
end tell
end try
If someone would be able to help me, that would be great.
Deleting files whose name ends with " alias"
To delete files from your Downloads folder whose name ends with " alias" use:
tell application "System Events" to delete (files of downloads folder whose name ends with " alias")
Important: Matching file names ending in " alias" doesn't ensure the files to be deleted are true aliases. Any real file(s) could also have a name ending in " alias" - in which case they will be deleted too.
Deleting files whose kind is "Alias"
To delete real aliases from your Downloads folder consider matching file(s) whose kind is "Alias" instead.
tell application "System Events" to delete (files of downloads folder whose kind is "Alias")
Note: This way avoids deleting any real file(s) which could have a name ending in " alias".
The delete command only likes single items, not lists, so can handle it with iteration. Also, use "System Events" when you can for such operations... it's much more stable.
Here's a script that works:
set theFolder to (path to downloads folder)
tell application "System Events"
set itemList to (disk items of downloads folder whose name ends with " alias")
repeat with thisItem in itemList
delete thisItem
end repeat
end tell

Applescript to copy files based on partial file name

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.

Loop stalling when deleting files

The script below is supposed to delete all files ending in .aux, etc.
in the current directory (i.e. directory displayed in the finder window)
The script seems to stall on deleting .aux files.
Any hint is welcome.
try
tell application "Finder"
set lieu to target of window 1
set finale to {".aux", ".log", ".bak", ".out", ".synctex.gz"} as list
repeat with x in finale
try
delete (every item of lieu whose name ends with x)
end try
end repeat
end tell
say "Mess cleaned up"
on error
display dialog ("Error. Couldn't Delete the File") buttons {"OK"}
end try
Here a version that uses rm:
tell application "Finder"
set lieu to target of window 1 as text
set posixPathOfLieu to POSIX path of lieu
set shellScript to "cd" & space & quoted form of posixPathOfLieu & ";rm *.aux *.log *.bak *.out *.synctex.gz"
try
do shell script shellScript
end try
end tell
Please be extremly careful when using rm. One space character at the wrong place can delete everything.

Accessing folders in AppleScript

Sorry, complete beginner here with AppleScripting.
I'm trying to do a very simple thing, move files from one folder to another.
tell application "Finder"
set this_folder to "Users:chris.nicol:Movies:SmartConverter:"
set this_list to every file of this_folder
repeat with i in this_list
--if i does not start with "x" then
move i to "users:chris.nicol:music:itunes:itunes media:automatically add to itunes:"
--end if
end repeat
end tell
However I keep getting an error:
I've tried different commands (count, parentContainer, etc.) on the folder, but I get the same type of error. I've tried different formatting for the folder ...
Users/chris.nicol/Movies/SmartConverter/
Macintosh HD:Users:chris.nicol:Movies:SmartConverter
etc.
Any ideas on what I'm doing wrong?
Thanks in advance,
Chris
Simple tip... if you want to find the proper path you should use try this and look in the results field for the proper path. You'll see that the name of the hard drive, Macintosh HD, is required. Note you could use "choose file" as well if you wanted the path to a file.
(choose folder) as text
Next, the path that you will see is a string. Applescript sees it as a string not a path to a file or folder. As such, when you want to use the string as a path then you must put the word "file" or "folder" in front of it as appropriate to make applescript use it properly. Therefore your script should look like this. Note that the move command can handle a list of files so the repeat loop isn't needed.
set this_folder to "Macintosh HD:Users:chris.nicol:Movies:SmartConverter:"
tell application "Finder"
set this_list to every file of folder this_folder
move this_list to folder "Macintosh HD:Users:chris.nicol:music:itunes:itunes media:automatically add to itunes:"
end tell
Try:
set thisFolder to (path to movies folder as text) & "SmartConverter"
set thatFolder to (path to music folder as text) & "itunes:itunes media:automatically add to itunes"
tell application "Finder" to move files of folder thisFolder to thatFolder
You must have some invisible or otherwise uncopyable files in one of the folders. Either add something like without invisibles to the end of your set this_folder line, or get rid of your loop altogether and simply call
move files of entire contents of this_folder to (the Add Automatically folder)

Resources