Find image files and copy it to a common directory failed
Linux - NewbieThis Linux forum is for members that are new to Linux.
Just starting out and have a question?
If it is not in the man pages or the how-to's this is the place!
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Find image files and copy it to a common directory failed
I am using ubuntu 11.10.
I have a directory containing lot a directories and many of these directories contain several image files, both in jpg and png formats. Some directories are empty also. There might be a total of 100 files. I am trying to copy all these image files and put it in a common directory. I used the following command.
But this didn't copy all the files of type jpg. It only copied 6 files to be exact. So, what modification should be done in the command to copy all the files.
Also, what should I do if I want to copy both *.jpg and *.png in one go.
You need to quote arguments that use wildcards. Otherwise they will expand to what *.jpg or *.png files are in the current directory, before the command is run.
Code:
set find ./ -iname *.pdf
:~/Documents/pdfs> echo ${*}
find ./ -iname 7007887b.pdf AIMagzine-DeepQA.pdf at.pdf avr-libc-user-manual-1.0.4.pdf BLUEBOOK.pdf Converting movies to .mp4 with VLC media player.pdf credentials.pdf manual3.pdf
I tried with quotes also. Still not working. I am only able to copy a few files.
@kbp: I do have permission in all the directories. I even did a chmod on the parent directory. If I do the first part only, that is the "find" part, the terminal will list all the 100 and odd jpg files I have in the parent directory. But, copying them is simply not working.
@catkin:There were no error messages.
One more thing. Suppose I have a folder called 'night' and it contains 5 jpg files. When I try to run the same command on this directory, it will find and then copy all the jpg files to the destination directory. But, when I do the operation on the parent directory, as I said earlier, it is not even copying the files inside 'night' to the destination directory.
Run the command without the -exec part and see what find finds. One possibility is that the filenames contain "evil" characters, so the cp command fails.
Often -print0 is used in the find command, and the results are piped to xargs with the -0 option. This uses NULL to separate the filenames.
Also look at xargs options to limit the number of arguments handled at one time. A command like "cp /source/*.jpg /target/dir/" could fail when the shell expands the * wildcard. You can run out of memory.
Another use of xargs is to add arguments from a file.
One more thing. Suppose I have a folder called 'night' and it contains 5 jpg files. When I try to run the same command on this directory, it will find and then copy all the jpg files to the destination directory. But, when I do the operation on the parent directory, as I said earlier, it is not even copying the files inside 'night' to the destination directory.
This sounds like you still are not quoting the arguments to -iname. You also need single quotes around '{}' to handle files with spaces.
For something as simple as this, I usually just skip find and do it by hand:
Code:
cp *.jpg */*.jpg */*/*.jpg /destination/
It's usually much faster doing it this way than futzing with find and passing filenames with illegal characters through exec, etc. It's only feasible if you only have a few levels of subdirectories and a few different extensions to look for though.
Edit: and if you still want to track down the find problem, stick an "echo" in front of your cp in the -exec, eg:
For the record, I didn't use single quotes for {} previously.
You got different results with and without the single quotes around {} ?
That's intriguing. I would like to understand how/why that happens. AFAIK they would be stripped by bash before find is run. On that basis they should (!) not make any difference.
Does this command show the "evil" characters (with and without single quotes around {}):
The "tr" commands translates between two character sets. "tr '\n' '\0' <filelist" takes its input from filelist and translates newlines to nulls. The results are printed to stdout, which is piped into xargs.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.