I need to excute in ubuntu something like this:
find ./ -name '*.jpg' -execdir "mogrify -quality 50 *.jpg" {} \;
To compact all the *.jpg to 50% of your quality but this need to be recursive, because i have 1350 files in a long tree of folders...
And this return ever something like:
mogrify: unable to open image `Banner-Caixa.jpg': permission denied # error/blob.c/OpenBlob/2712.
I discovered!
sudo find . -name '*.jpg' -execdir sh -c "mogrify -quality 50 *.jpg" {} \;
This works fine!
widoth / on ./ and add sh -c after -execdir
Related
Am trying to create one and add the same to the cron.
This is the commands I am trying to run through the script.
#!/bin/bash
find . -mmin -60 -name "*.jpg" $(printf "! -name %s " $(cat processed.txt) ! -name cache) -exec convert -resize 1000x800 -quality 85% {} {};
find -mmin -60 -type f -name "*.jpg" -exec basename {} \; &> processed.txt
f I am running these commands directly on shell, I don't get any error.
but if say I have stored this in a file called compress and run the script as ./compress
I get the error -
find: missing argument to `-exec'
what mistake I am making and how I can fix that.
Build an array of arguments for the first find command instead of relying on the command substitution.
while IFS= read -r line; do
processed+=(! -name "$line")
done < processed.txt
Your immediate problem, though, is that you forgot to escape the semicolon so that it would be treated as an argument to find, rather than a command terminator.
find . -mmin -60 -name "*.jpg" "${processed[#]}" \
! -name cache -exec convert -resize 1000x800 -quality 85% {} {} \;
# ^^
find -mmin -60 -type f -name "*.jpg" -exec basename {} \; &> processed.txt
Want copy all files from catalog /usr/sbin to other folder with range beetwen 500kb and a 4M.
First line of code, that I write it's normally do.
find /usr/sbin/ type -f -size +500k -size -4M
But when I add -exec code action above to do it's print err:
find /usr/sbin/ type -f -size +500k -size -4M -exec cp /usr/sbin '/dest-catalog'
find: missing argument to `-exec`
Try 'find --help' for more information
Can't find any answer despite study man, find --help, search answer.
Ok, thanks RavinderSingh13 & 123. Found solution write this code:
find /dest_catalog/ -type f -size +500k -size -4M -exec cp -nv {} ./ \;
I have successfully installed optipng and jpegoptim but trying to optimize directory and its not working
I'm trying to run this code
jpegoptim -d/home/user/folder/images -name *.jpg
"its not working" is not an error message, please post the actual output with the error message, but looking at the manpage I gather that -name is not an option.
Try:
find /path/to -regex ".*\.\(jpg\|jpeg\)" -exec jpegoptim -d/home/user/folder/images '{}' \+
Following command will find all jpegs within images path and execute jpegoptim to optimise these images:
find /path/to/images/ -type f -iname *.jpg -exec jpegoptim --max=60 --all-progressive -p {} \;
In Your case you can replace path and use following command:
find /home/user/folder/images/ -type f -size +1000k -iname *.jpg -exec jpegoptim --max=60 --all-progressive -p {} \;
UPDATE 2014-03-21
So I realized I wasn't as efficient as I could be, as all the disks that I needed to "scrub" were under /media and named "disk1, disk2,disk3, etc." Here's the final script:
DIRTY_DIR="/media/disk*"
find $DIRTY_DIR -depth -type d -name .AppleDouble -exec rm -rf {} \;
find $DIRTY_DIR -depth -type d -name .AppleDB -exec rm -rf {} \;
find $DIRTY_DIR -depth -type d -name .AppleDesktop -exec rm -rf {} \;
find $DIRTY_DIR -type f -name ".*DS_Store" -exec rm -f {} \;
find $DIRTY_DIR -type f -name ".Thumbs.db" -exec rm -f {} \; # I know, I know, this is a Windows file.
Next will probably to just clean up the code even more, and add features like logging and reporting results (through e-mail or otherwise); excluding system and directories; and allowing people to customize the list of files/directories.
Thanks for all the help!
UPDATE
Before I incorporated the helpful suggestions provided by everyone, I performed some tests, the results of which were very interesting (see below).
As a test, I ran this command:
root#doi:~# find /media/disk3 -type d -name .AppleDouble -exec echo rm -rf {} \;
The results (which is what I expected):
rm -rf /media/disk3/Videos/Chorus/.AppleDouble
However, when I ran the actual command (without echo):
root#doi:~# find /media/disk3 -type d -name .AppleDouble -exec rm -rf {} \;
I received the same "error" output:
find: `/media/disk3/Videos/Chorus/.AppleDouble': No such file or directory
I put "error" in quotes because obviously the folder was removed, as verified by immediately running:
root#doi:~# find /media/disk3 -type d -name .AppleDouble -exec rm -rf {} \;
root#doi:~#
It seems like the find command stored the original results, acted on it by deleting the directory, but then tried to delete it again? Or is the -f option of rm, which is supposed to be for ignoring nonexistent files and arguments, is ignored? I note that when I run tests with the rm command alone without the find command, everything worked as expected. Thus, directly running rm -rf ... \nonexistent_directory, no errors were returned even though the "non_existent_directory" was not there, and directly running rm -r \nonexistent_directory provided the expected:
rm: cannot remove 'non_existent_directory': No such file or directory
Should I use the -delete option instead of the -exec rm ... option? I had wanted to make the script as broadly applicable as possible for systems that didn't have -delete option for find.
Lastly, I don't presume it matters if /media/disk1, /media/disk2, ... are combined in an AUFS filesystem under /media/storage as the find command is operating on the individual disks themselves?
Thanks for all the help so far, guys. I'll publish the script when I'm done.
ORIGINAL POST
I'm writing a bash script to delete a few OS X remnants on my Lubuntu file shares. However, when executing this:
...
BASE_DIR="/media/disk" # I have 4 disks: disk1, disk2, ...
COUNTER=1
while [ $COUNTER -lt 5 ]; do # Iterate through disk1, disk2, ...
DIRTY_DIR=${BASE_DIR}$COUNTER # Look under the current disk counter /media/disk1, /media/disk2, ...
find $DIRTY_DIR -name \.AppleDouble -exec rm -rf {} \; # Delete all .AppleDouble directories
find $DIRTY_DIR -name ".*DS_Store" -exec rm -rf {} \; # Delete all .DS_Store and ._.DS_Store files
COUNTER=$(($COUNTER+1))
done
...
I see the following output:
find: /media/disk1/Pictures/.AppleDouble: No such file or directory
Before I added the -exec rm ... portion the script found the /media/disk1/Pictures/.AppleDouble directory. The script works properly for removing DS_Store files, but what am I missing for the find command for directories?
I'm afraid to screw too much with the -exec portion as I don't want to obliterate directories in error.
tl;dr - Pass -prune if you're deleting directories using find.
For anyone else who stumbles on this question. Running an example like this
find /media/disk3 -type d -name .AppleDouble -exec rm -rf {} \;
results in an error like
rm: cannot remove 'non_existent_directory': No such file or directory
When finding and deleting directories with find, you'll often encounter this error because find stores the directory to process subdirectories, then deletes it with exec, then tries to traverse the subdirectories which no longer exist.
You can either pass -maxdepth 0 or -prune to prevent this issue. Like so:
find /media/disk3 -type d -name .AppleDouble -prune -exec rm -rf {} \;
Now it deletes the directories without any errors. Hurray! :)
You don't need to escape DOT in shell glob as this is not regex. So use .AppleDouble instead of \.AppleDouble:
find $DIRTY_DIR -name .AppleDouble -exec rm -rf '{}' \;
PS: I don't see anywhere $COUNTER being incremented in your script.
I want to rename all .hg_gg folders in /var/www to .hg. How can I do it?
I know how to rename .hg to .hg_gg.
find /var/www -name ".hg" -exec bash -c 'mv $0 $0_gg' {} \;
but don't know how to make reverse change.
Try this:
find /var/www -name ".hg_gg" -execdir bash -c 'mv {} .hg' \;
You need to use a special syntax defined by find: {} is the placeholder for the current file name. Check the man page for that. Also it is important to use -execdir instead of -exec. execdir changes the current working directory to the folder where the found directory is located. Otherwise it would do something like this mv /var/www/.hg_gg ./.hg
You can speed up things a bit when restricting find to find folders only using -type d:
find /var/www -type d -name ".hg_gg" -execdir bash -c 'mv {} .hg' \;
Consider this find command with -execdir and -prune options:
find /var/www/ -type d -name ".hg_gg" -execdir mv '{}' '.gg' \; -prune
-execdir will execute the command in each subdirectory
-prune causes find to not descend into the current file
Not a one liner, but you could do this:
for file in `find /var/www -name ".hg_gg"`; do
mv $file `echo $file | sed 's/hg_gg$/hg/'`
done