I am trying to use the following command to find all PDFs in the current directory (not recursively) - however I don't think it likes the '{}' on the --out.
find . -iname "*.pdf" -maxdepth 1 -exec sips -s format jpeg --resampleHeightWidth 129 100 '{}' --out '{}'.jpg \;
The find work when used with -print and sips works when I specify the name --out test.jpg. Any way to make this work? Or should I try xargs? I don't really want to use a loop for simplicity... Any ideas?
UPDATE:
I attempted using xargs - but again get an error out_dir_not_found.
find . -iname "*.pdf" -maxdepth 1 -print0 | xargs -0 -I % sips -s format jpeg --resampleHeightWidth 129 100 % --out "%.jpg"
mymbpro:pdfs dh$ find . -iname "*.pdf" -maxdepth 1 -print0 | xargs -0 -I % sips -s format jpeg --resampleHeightWidth 129 100 % --out "%.jpg"
Error 10: out_dir_not_found /Users/darenhunter/Desktop/pdfs/ATTENTION.pdf.jpg
Try 'sips --help' for help using this tool
Error 10: out_dir_not_found /Users/darenhunter/Desktop/pdfs/DisNCLB119.pdf.jpg
Try 'sips --help' for help using this tool
Error 10: out_dir_not_found /Users/darenhunter/Desktop/pdfs/services2012.pdf.jpg
Try 'sips --help' for help using this tool
Error 10: out_dir_not_found /Users/darenhunter/Desktop/pdfs/Fall2011.pdf.jpg
Try 'sips --help' for help using this tool
If you will be executing over many results, it is more efficient to pipe the
results to the xargs command instead. xargs is a more modern
implementation, and handles long lists in a more intelligent way. The
print0 option can be used with this.
The following command will ensure that filenames with whitespaces are passed
to the executed COMMAND without being split up by the shell. It looks
complicated at first glance, but is widely used.
find . -print0 | xargs -0 COMMAND
ref
Related
I am trying to execute a command depending on the file type within directory. But am unable to check the content within directory using wildcard. When provided a literal filename I am able to execute.
find ./* -type d -execdir bash -c 'DIR=$(basename {}); if [[ -e {}/*.png ]]; then echo "img2pdf {}/*.png -o $DIR.pdf"; fi ' \;
Instead of going over directories, and then looking for png-s inside, find can find png-s straight away:
find . -name '*.png'
Then you can process it as you do, or using xargs:
find . -name '*.png' | xargs -I '{}' img2pdf '{}' -o '{}.pdf'
The command above will process convert each png to a separate pdf.
If you want to pass all png-s at once, and call img2pdf once:
find . -name '*.png' | xargs img2pdf -o out.pdf
I am trying to iterate over a large number of images and check their 'mean' value using ImageMagick.
The following command finds the images I want to check, and executes the correct command on them.
find `pwd` -type f -name "*.png" -exec /usr/bin/identify -ping -format "%[mean]" info: {} \;
Now I want to compare the output to see if it comes up with a certain value, 942.333
How can I get the output of each value that find returns to check and spit out the filename of any matched image who has the ouput of 942.333 from my command?
Thanks!
Change your identify command so it outputs the filename and the mean, then use grep:
find `pwd` -type f -name "*.png" -exec identify -ping -format "%[mean] %f\n" {} \; | grep "942.333"
Or, if you really have lots of images, you could put all your lovely CPU cores to work and do them in parallel, using GNU Parallel:
find . -name \*.png -print0 | parallel -m -0 'identify -ping -format "%[mean] %f\n" {1}' | grep ...
Im learning unix programming , i want to find all files whose size is greater than 1M an print them into a file.
here is my code
find. -size +1M -print0 | xargs -I -O '{}' mv '{}' files
all sites i have found refer to this one as right one , but it does not work . currently im working on ubuntu
You mis-copied/mis-typed the commend from wherever you found it.
The first {} is the argument to -I.
-O is not an argument to xargs you meant -0 (to go with -print0).
You missed the space between find and . (the current directory).
Which would get you:
find . -size +1M -print0 | xargs -0 -I '{}' mv '{}' files
That being said you don't need xargs here at all since find can execute commands directly.
find . -size +1M -exec mv {} files \+
And it is generally a good idea to test a complicated find command before you run it.
Using find . -size +1M by itself will just print the matching files.
Using
find . -size +1M -ok mv {} files \+
will cause find to prompt you before each execution of the command.
I want to move all the files in a specific folder having size of 0 bytes. I know that the following prints all the files with size zero bytes.
find /home/Desktop/ -size 0
But i want to move them to another folder, so i tried :
find /home/Desktop/ -size 0 | xargs -0 mv /home/Desktop/a
But that doesn't work. ? Is there any other way to do it.? What am i doing wrong?
You can do that in find itself using -exec option:
find /home/Desktop/ -size 0 -exec mv '{}' /home/Desktop/a \;
find default prints the file name on the standard output followed by a newline. The option -print0 prints the file name followed by a null character instead. The option -0 of xargs means that the input is terminated by a null character.
find /home/Desktop/ -size 0 -print0 | xargs -0 -I {} mv {} /home/Desktop/a
You could instead use find's option -exec
In both cases consider also using find's option -type f if you only want to find files and the option -maxdepth 1 if you do not want find to descend directories. This is specially usefull in your example since you move the found files to a subdirectory!
Ok, I got a directory (for instance, named '/photos') in which there are different directories
(like '/photos/wedding', '/photos/birthday', '/photos/graduation', etc...) which have .jpg files in them. Unfortunately, some of jpeg files are broken. I need to find a way how to determine, which files are broken.
I found out, that there is tool named imagemagic, which can help a lot. If you use it like this:
identify -format '%f' whatever.jpg
it prints the name of the file only if file is valid, if it is not it prints something like "identify: Not a JPEG file: starts with 0x69 0x75 `whatever.jpg' # jpeg.c/EmitMessage/232.".
So the correct solution should be find all files ending with ".jpg", apply to them "identify", and if the result is just the name of the file - don't do anything, and if the result is different from the name of the file - then save the name of the file somethere (like in a file "errors.txt").
Any ideas how I can probably do that?
The short-short version:
find . -iname "*.jpg" -exec jpeginfo -c {} \; | grep -E "WARNING|ERROR"
You might not need the same find options, but jpeginfo was the solution that worked for me:
find . -type f -iname "*.jpg" -o -iname "*.jpeg"| xargs jpeginfo -c | grep -E "WARNING|ERROR" | cut -d " " -f 1
as a script (as requested in this question)
#!/bin/sh
find . -type f \
\( -iname "*.jpg" \
-o -iname "*.jpeg" \) \
-exec jpeginfo -c {} \; | \
grep -E "WARNING|ERROR" | \
cut -d " " -f 1
I was clued into jpeginfo for this by http://www.commandlinefu.com/commands/view/2352/find-corrupted-jpeg-image-files and this explained mixing find -o OR with -exec
One problem with identify -format is that it doesn't actually verify that the file is not corrupt, it just makes sure that it's really a jpeg.
To actually test it you need something to convert it. But the convert that comes with ImageMagick seems to silently ignore non-fatal errors in the jpeg (such as being truncated.)
One thing that works is this:
djpeg -fast -grayscale -onepass file.jpg > /dev/null
If it returns an error code, the file has a problem. If not, it's good.
There are other programs that could be used as well.
You can put this into bash script file or run directly:
find -name "*.jpg" -type f |xargs --no-run-if-empty identify -format '%f' 1>ok.txt 2>errors.txt
In case identify is missing, here is how to install it in Ubuntu:
sudo apt install imagemagick --no-install-recommends
This script will print out the names of the bad files:
#!/bin/bash
find /photos -name '*.jpg' | while read FILE; do
if [[ $(identify -format '%f' "$FILE" 2>/dev/null) != $FILE ]]; then
echo "$FILE"
fi
done
You could run it as is or as ./badjpegs > errors.txt to save the output to a file.
To break it down, the find command finds *.jpg files in /photos or any of its subdirectories. These file names are piped to a while loop, which reads them in one at a time into the variable $FILE. Inside the loop, we grab the output of identify using the $(...) operator and check if it matches the file name. If not, the file is bad and we print the file name.
It may be possible to simplify this. Most UNIX commands indicate success or failure in their exit code. If the identify command does this, then you could simplify the script to:
#!/bin/bash
find /photos -name '*.jpg' | while read FILE; do
if ! identify "$FILE" &> /dev/null; then
echo "$FILE"
fi
done
Here the condition is simplified to if ! identify; then which means, "did identify fail?"