(AppleScript) Remove files from subfolders with shell script - macos

I have a script that moves files to Trash, but I work with tens of thousands of files so I need it to do fast. Current script gets Finder stuck and I need to relaunch Finder every time I use the script.
set source_folder to POSIX path of (path to pictures folder) & "4K Stogram"
do shell script "/usr/bin/find " & quoted form of source_folder & " -type f -exec /bin/mv {} ~/.Trash \\;"
display notification "All images were processed." with title "New" sound name "Glass.aiff"
tell me to quit
Wouldn't the shell script's 'rm -f' command make it faster?
How the script should look like if yes?
I don't need those files in Trash anyway, I delete them right after the script finishes the job.

Add the -delete option to the find command.
Like this:
set source_folder to POSIX path of (path to pictures folder) & "4K Stogram"
do shell script "/usr/bin/find " & (quoted form of source_folder) & " -type f -delete"

You should be able to pipe your find results to the rm command. Understand that although rm should be faster, it is permanent. Be sure that your code is correct before invoking it.

Related

How to get name of folder for Shell Script in Automator?

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

Locate a file anywhere on the hard drive and transfer it to a different folder

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/"

Compress folder in archive named as folder

I want to make a little script to compress folder. In fact I want to do exactly what is done when you right clic on a folder and select "compress": the zip file has the same name as the folder and when you clic on it, it creates back the folder and the files.
Here is my code:
set the_src to "Mac Info:Users:Maison:Desktop:Dest_So36"
set the_src to quoted form of POSIX path of the_src
set the_dest to "Mac Info:Users:Maison:Desktop:Dest_So36.zip"
set the_dest to quoted form of POSIX path of the_dest
do shell script "cd " & the_src & ";zip -r " & the_dest & " *"
If I use zip -r it takes all sub folder and file from the orginal folder but when unpacking, it give back the content of the original folder (subfolder and files) but not the main folder itself.
It I use zip -jr, it loose all the sub-folder (it get the files but not the folder).
Thanks
Changing the directory is fine. You don't need the asterisk.
do shell script "cd '/Users/Maison/Desktop/'; zip -r 'zip-a-dee-doo-dah.zip' 'Dest_So36' "
Why are you using cd (changedirectory) to go INTO the folder?
When you are in the parent folder, you can use the zip -r command and it will work.
So I believe you command should become:
do shell script "zip -r " & the_dest & ".zip" & the_dest

merge folder in current directory using applescript

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.

Bash Shell Script to search for files using mdfind

I have a folder of about 350 images (they are scanned recipes). To make finding them easier, I have written a search program in bash shell script. I have bash version 3.2 on Mac OS X 10.8 Mountain Lion.
The basic idea of my program:
Ask the user for search terms (using osascript).
Search the file (names) for the search terms, using mdfind.
Send the matching files to ln (through xargs).
Make a hardlink of matching files in a "results" directory. This directory is contained within the same folder of images (this directory is cleaned at the beginning of the program).
What the directories look like:
+Recipes
-files
-files
-files
+.search
-search (shell script)
+results
-links
-links
Here's my code:
#!/bin/bash
#
# Search program for recipes.
# version 2
# Clean out results folder
rm -rf ~/Google\ Drive/Recipes/.search/results/*
# Display the search dialog
query=$(osascript <<-EOF
set front_app to (path to frontmost application as Unicode text)
tell application front_app to get text returned of (display dialog "Search for:" default answer "" with title "Recipe Search")
EOF)
# If query is empty (nothing was typed), exit
if [ "$query" = "" ]
then
exit
fi
echo "Searching for \"$query\"."
# Search for query and (hard) link. The output from 'ln -v' is stored in results
# 'ln' complains if you search for the same thing twice... mdfind database lagging?
results=$(mdfind -0 -onlyin ~/Google\ Drive/Recipes/ "$query" | xargs -0 -J % ln -fv % ~/Google\ Drive/Recipes/.search/results)
if [ "$results" ]
then
# Results were found, open the folder
open ~/Google\ Drive/Recipes/.search/results/
else
# No results found, display a dialog
osascript <<-EOF
beep
set front_app to (path to frontmost application as Unicode text)
tell application front_app to display dialog "No results found for \"" & "$query" & "\"." buttons "Close" default button 1 with icon 0
EOF
fi
It works fine—the first time. If you search for the same thing twice, it breaks.
Explanation: let's say I search for "chicken". 34 files match, and hard links are made in the results directory.
Now, I run the program again, and search for the same thing—"chicken". The directory is emptied (by rm). But now, the finding/linking stops working—only 6 or 7 recipes will be linked. What seems to be happening is that mdfind is finding the results in the search directory, after they have been deleted, and then ln can't make links. But it doesn't find the main files...
I get
ln: ~/Google Drive/Recipes/.search/results/recipe.jpg: no such file or directory
I looked at mdfind used for creating symlinks not working as expected; they have a similar problem (but no help).
Thanks for any help... this has been annoying me for a long time.
You can re-index directories or files with mdimport.
$ touch aa
$ mdfind -onlyin . -name aa
/Users/lauri/Desktop/aa
$ rm aa
$ mdimport .
$ mdfind -onlyin . -name aa
$
Spotlight doesn't index directories that start with a period, so you could just rename the .search directory.
The Spotlight commands use a cached index of the file contents. I don't know of any way to force mdfind not to do so. The brute force approach is to clear the cache with mdutil -E after removing the files, but you may not want to do that.

Resources