I have this shell script which resolves a symbolic link (symlink) to a folder and copies it to the current working directory:
cp -R `grealpath /some/dir/symlink_to_folder` .
The command grealpath just resolves a symbolic link when coreutils are installed on Mac OS X.
My question is: What would be the equivalent as an AppleScript? The workflow would be ideally like this: Copy one or more symbolic link-folders in Finder to the clipboard, then rightclick on another folder in Finder -> services -> run the newly created script to copy all symlinks from the clipboard to the other folder.
You could create a service like this:
cp -R "$(/usr/local/bin/grealpath "$(osascript -e 'POSIX path of «class furl» of (the clipboard as record)')")" "$1"
If the clipboard contains references to files, «class furl» of (the clipboard as record) returns a file object for the first file.
You might also use cp -RH source target instead of cp -R `grealpath source` target. If the symlink and its target have different names, it uses the name of the symlink though.
-H If the -R option is specified, symbolic links on the command line
are followed. (Symbolic links encountered in the tree traversal
are not followed.)
Applescript will treat a symlink like it's just another folder, so all you have to do is duplicate the contents.
Tell application "Finder"
repeat with i from 1 to (count symlinks)
set newFolder to make new folder at destFolder with properties {name:item i of symlinks)
duplicate entire contents of item i of symlinks to newFolder
end
Related
I'm using the newest version of macOS Monterey.
Sometimes I have to merge/combine all files that are in a specific folder into one txt file.
I currently do that by typing this in Terminal:
cd /Users/my_name/Desktop/test_folder ; cat * >merged.txt
This will merge/combine all files in folder test_folder into one file called merged.txt. The file merged.txt will get saved into the folder test_folder.
Every time I need this I have to open Terminal copy/paste the command and replace test_folder with the right folder name, since it's not always the same.
I want to make this easier by just make a right click on a folder, go to Quick Actions and select e.g. Merge all files to merge/combine all files inside the folder I just clicked on.
But I stuck at getting the folder name. How can I dynamically get the folder name and path I clicked on to start this Quick Action instead of the hard coded /Users/my_name/Desktop/test_folder?
Or, is there another and easier solution?
This is what I have so far:
I wouldn’t do this with AppleScript, especially if all it’s ultimately doing is calling out to a shell script.
Stick with the Run Shell Script action except change the option for passing the input as arguments rather than to stdin.
The folders selected in Finder will then be available to your script via $#, so you can do something like:
for d in "$#"; do
cat "$d"/* > "$d/merged.txt"
open -R "$d/merged.txt"
done 2>/dev/null
This loops through the selected directories and concatenates the files to merged.txt in the respective directory. The open -R line reveals the merged.txt file in Finder.
Errors are written to /dev/null, i.e. discarded, as cat will throw an error if any of the directories, themselves, contain directories.
Instead of adding a Run Shell Script to your workflow, try adding a Run AppleScript command instead. Copy this following AppleScript code to the Run AppleScript command.
on run {input, parameters}
try
do shell script "cd " & quoted form of POSIX path of input & " && cat *.txt > merged.txt"
on error
try
do shell script "cd " & quoted form of POSIX path of input & " && rm merged.txt"
end try
end try
end run
I'm an applescript noob. So I don't know anything about this type of coding.
I want to make a script for a watch folder. I work with an image program that processes images. The process takes a second to create the jpg. So the folder has to wait for a few seconds to move the image to another file.
So this is what I'm looking for: Empty folder - jpg in the folder - wait 2 sec - move jpg to another folder - empty folder.
Thank you!
This AppleScript will accomplish what you asked. By the very nature of AppleScript, reading it should be very self explanatory as to what each line does:
on adding folder items to ThisFolder after receiving SomeFiles
set ThatFolder to POSIX file "/path/to/new/folder"
delay 2
repeat with TheFile in SomeFiles
tell application "Finder" to ¬
if name extension of (TheFile as alias) is in {"JPG", "JPEG"} then ¬
move TheFile to ThatFolder
end repeat
end adding folder items to
This is designed to run as a folder action, which makes the folder you choose automatically monitored by MacOS so that, whenever it detects a change to that folder, it executes the script attached to it. In this instance—as you can infer from the first line of the script—this will automatically run each time a file is added to the folder in question.
To set up a folder action:
Copy the AppleScript above into Script Editor. Edit the second line to replace "/path/to/new/folder" with the path to the new folder into which you want your jpegs to be moved (keep the quotes). I wouldn't bother trying to run the script from inside the editor—it won't work. The path you type out must be in full, i.e. "/Users/Richard/Pictures/Processed" and not "~/Pictures/Processed".
Save it as whatever you like. However, it must be saved in the following directory: ~/Library/Scripts/Folder Action Scripts where ~ indicates your Home folder (i.e. /Users/Richard/ or whatever it is). If the folder "Folder Action Scripts" doesn't exist, create it.
Close Script Editor. Navigate to the folder that is going to be watched, i.e. the folder that your images will be waiting initially. Now navigate one level up, into the directory containing said folder.
Right-click on the folder and hover over the Services menu item at the bottom. Then select Folder Actions Setup...
Enable folder actions by checking the box at the top. If you folder doesn't already appear in the left-hand list, you can add it. Then, in the right-hand list, click the '+' at the bottom and the script you just saved should be one of many in the list of scripts that pop up. Select it and add it.
Make sure the check boxes next to your watched folder and your chosen script are both checked, and you're done.
Now, whenever the folder receives any files whatsoever, that script is executed. The script will move any files with extensions .jpg or .jpeg into your new folder. Just make sure the new folder already exists (I didn't incorporate a line to create it if it doesn't; the script will just throw an error and your image won't be moved).
Here is a little sample script which you could save on your Desktop as monitor:
#!/bin/bash
# Source directory to watch and destination directory to copy to
SRC="$HOME/Desktop/source"
DST="$HOME/Desktop/dest"
# Create directories if not existent
mkdir -p "$SRC" "$DST"
while : ; do
find "$SRC" -type f -iname "*.jpg" -Btime +2s -exec mv {} "$DST" \;
sleep 5
done
It basically watches a directory called Desktop/source and looks for any files in there whose name ends in "JPG" and which have not been modified in the last 2 seconds. If it finds any, it then moves them to directory called Desktop/dest and sleeps for 5 seconds before checking again.
You would need to start Terminal and make the script executable by typing:
chmod +x $HOME/Desktop/monitor
Then, whenever you want it running, you just double-click on the icon of monitor on your Desktop.
I'm trying to create an app to transfer any files with a certain name a different folder. So far, I have the following:
tell application "Finder"
move (every item of (get path to home folder) whose name is "extended image name.jpg") to ((get path to home folder) & "Pictures" as string)
end tell
While this doesn't return any errors, it doesn't do what I want it to either. I am also aware that this only searches the home folder, so if there is any way to do a broader search of the whole drive without having to enter a username, that would be great (I want this to be able to run on more computers than one without them having to edit the script.)
-Thanks
The code considers only files in the home folder but not in its subfolders, to consider all subfolders you have to add entire contents
tell application "Finder"
move (every item of entire contents of home whose name is "extended image name.jpg") to folder "Pictures" of home
end tell
But be aware that entire contents is extremely slow. The shell command find or a spotlight search with mdfind is much faster for example
set homeFolder to POSIX path of (path to home folder)
set picturesFolder to POSIX path of (path to pictures folder)
do shell script "mdfind -onlyin " & quoted form of homeFolder & " -0 'kMDItemDisplayName = \"extended image name.jpg\"' | xargs -0 -J {} mv {} " & quoted form of picturesFolder
Important Note:
As you are moving multiple files with the same name the Finder version will ask for overwriting and the shell version will overwrite all files with the same name.
When you use the Finder to search, if your folder contains only few hundreds files that's OK. But if you want to search in a folder containing thousands of files, Finder will take too long. In this case, it is better to use the shell command 'find' which is much faster.
Syntax of find command is : find directory/ -name target_file_name
Even more, you can chain that command with -exec fonction which will used result of the find to do something: in your case to copy files found in Pictures folder.
In -exec command the {} means the file found. The shell copy command is cp.
This ends with : find /Users/myUserName/ -name 'extended image name.jpg' -exec cp {} \;
(note: the \; tells the system that's the end of the -exec command)
Overall you can run this command in Applescript via do shell script :
set Source to POSIX path of (path to home folder)
set Dest to POSIX path of (path to pictures folder)
set TargetName to "extended image name.jpg"
set BackSlash to ASCII character 92
set SemiCol to ASCII character 59
try
do shell script "find " & Source & " -name " & quoted form of TargetName & " -exec cp {} " & Dest & " " & BackSlash & SemiCol
end try
It is much longer than Finder syntax, but also much faster to run !
Notes:
1) the POSIX path convert the Finder path with : to shell path with /
2) the Backslash and SemiCol are set to \ and ; . this is a work around to avoid that Applescript compiler misinterpret the \ during compilation
3) the do shell script is in try/end try block to avoid error. "Find" gives errors when you try to access to files without permission. Such errors will be ignored.
4) with this method, you can replace Source by "/". Doing so, the find will search in all directories of the main drive (it may take some time !). If you want to search for all users, set Source to "/Users/"
Im wondering how to copy a folder that resides in the applescripts running directory to a specific folder on the MAC, making sure to merge the files/folders inside?
Cheers
K
set The_Moving_Folder to "Macintosh HD:Users:ComputerName:Desktop:Test1"
set The_Overwrite_Move_Location to "Macintosh HD:Users:ComputerName:Desktop:Test2"
do shell script "mv " & quoted form of (posix path of The_Moving_Folder) & " " & quoted form of (posix path of The_Overwrite_Move_Location)
The mv command will move directory paths from point A to point B. Not sure if this is exactly what you're looking for because you have no code up. However based on the question and comment, this should do the trick. If you're looking at moving a file to a folder than you want the cp command.
For more data about these commands, run man command_name in terminal.
I'm doing some repetitive work that involves creating a directory and duplicating a set of files into it. What i'm looking for is a script that will automate that process for me, which I can put into an Alfred workflow and just call up every time I need it.
I've gotten so far as a script that will create the directory in my front most Finder window, but I want that directory to contain duplicates of 4 specific files.
d="$(osascript -e 'tell app "Finder"
POSIX path of (insertion location as alias)
end')/new folder"
mkdir "$d"
cp /path/to/files/* "$d"
open -R "$d"
Or using AppleScript:
tell application "Finder"
set d to make new folder at (get insertion location) with properties {name:"new folder"}
duplicate files of (POSIX file "/path/to/files/" as alias) to d
reveal d
end tell