LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   cp -R doesn't search recursively (https://www.linuxquestions.org/questions/linux-newbie-8/cp-r-doesnt-search-recursively-4175607948/)

Sideroxylon 06-15-2017 02:14 AM

cp -R doesn't search recursively
 
Code:

sudo cp -R /mnt/old-hdd1/{*.jpg,*.png,*.gif,*.jpeg,*.bmp,*.tiff} /home/name/restore/pics/
I think this command tells cp to search in all sub-sequent folders of "old-hdd1/" but it never copies any pictures, even though I KNOW for certain that there are enough, especially .jpg ones that I included in the cp command.
Did I phrase the command wrongly or is something wrong with the system?

rtmistler 06-15-2017 06:26 AM

Hi Sideroxylon and welcome to LQ.

I haven't used that type of a command to find and copy specific file types. Instead what I do is to use a find -exec command, such as:
Code:

$ sudo find /mnt/old-hdd1 -name "*.jpg" -exec cp {} /home/name/restore/pics/. \;
However before doing the -exec portion, I'd see what the find, would find, by not having the -exec term. Note you can also use the search spec "*.jp*" to find both jpg and jpeg extensions.

aragorn2101 06-15-2017 06:39 AM

Hi Sideroxylon and welcome to LQ,

The "-R" option for cp certainly means copy while accessing directories recursively, but the culprit here is the {}.

If you expand your command you will understand what's going on:
Code:

> cp -R /mnt/old-hdd1/{*.jpg,*.png,*.gif,*.jpeg,*.bmp,*.tiff} DESTPATH

actually becomes

> cp -R /mnt/old-hdd1/*.jpg /mnt/old-hdd1/*.png /mnt/old-hdd1/*.gif /mnt/old-hdd1/*.jpeg /mnt/old-hdd1/*.bmp /mnt/old-hdd1/*.tiff DESTPATH

So, the command is actually looking for pictures immediately under /mnt/old-hdd1/ instead of recursively. Normally, the "-R" argument is used when copying entire directories and any subdirectories along. When you are looking for specific files or types of files, it is better to do a search first, like what rtmistler suggested with the find command. I invite you to read the man page for the find command. It is a very powerful command and will surely be useful in the future.

sweepnine 06-15-2017 06:41 AM

Quote:

Originally Posted by Sideroxylon (Post 5722900)
Code:

sudo cp -R /mnt/old-hdd1/{*.jpg,*.png,*.gif,*.jpeg,*.bmp,*.tiff} /home/name/restore/pics/

I guess the files are in some subfolders below /mnt/old-hdd1/. With the command above you only hit the files that are directly in /mnt/old-hdd1/. For instance /mnt/old-hdd1/bold/beng.jpg does not match /mnt/old-hdd1/*.jpg but is does match /mnt/old-hdd1/bold/*.jpg .

syg00 06-15-2017 07:05 AM

Quote:

Originally Posted by aragorn2101 (Post 5722964)
I invite you to read the man page for the find command. It is a very powerful command and will surely be useful in the future.

Well meant no doubt, but there be dragons - the find manpage is about the most inscrutable in existence.

Sideroxylon 06-15-2017 08:35 AM

Thank you for extensive explanation, I understand now. Well, first of all I really wanted to copy the files and not only search. I guess I didn't make it clear enough since I used the word "search" in connection with the cp command. Secondly, this was my thought:
1. cp -R /one/pc/dir/ copies recursively
2. {*.png,*.etc} copies different file types

1. + 2. = 3. copies different file types recursively.

But I understand now that it obviously works differently when combining these two.

rtmistler 06-15-2017 08:48 AM

Quote:

Originally Posted by Sideroxylon (Post 5723004)
Thank you for extensive explanation, I understand now. Well, first of all I really wanted to copy the files and not only search. I guess I didn't make it clear enough since I used the word "search" in connection with the cp command. Secondly, this was my thought:
1. cp -R /one/pc/dir/ copies recursively
2. {*.png,*.etc} copies different file types

1. + 2. = 3. copies different file types recursively.

But I understand now that it obviously works differently when combining these two.

I agree with your starting philosophy and in fact had that perception once myself.

I've learned over time that I really do wish to search in advance to know what it will find and copy, or do some other operation I'm working on.

Per aragorn2101's and syg00's points. The man pages are both, "very helpful and usually 100% correct", and also "sometimes elusive or difficult to read/interpret".

I learned find incrementally. First how to find a file from the current working directory of a certain pattern name (regular expression I believe applies here). Then I learned how to do the -exec portion. That's about it, find may have tons more properties, but that seems to have served me well.

On the other side, I absolutely moved away from cp -R for when I did not wish to copy an entire tree unconditionally. I would use that, or the -a flag to copy an entire tree. But to locate only certain pattern filenames and do something with them, I stick with find.

Sideroxylon 06-15-2017 11:13 AM

Code:

sudo find . -iname "*.jpg" -iname "*.jpeg" -iname "*.png" -iname "*.gif" -iname "*.bmp" -iname "*.tiff"
I used this one but it gives no output.

Sideroxylon 06-15-2017 11:16 AM

Quote:

Originally Posted by rtmistler (Post 5723009)
I've learned over time that I really do wish to search in advance to know what it will find and copy, or do some other operation I'm working on.

Actually I already did search for all files on the drive including picture, that's also why I certainly know that there are pictures of these types. But it doesn't help me, because I obviously can't just copy paste the output of ls into a cp command.

sweepnine 06-15-2017 11:44 AM

The find-cmd as suggested by rtmistler is nontheless best way for you though a bit steep.

Quote:

Originally Posted by Sideroxylon (Post 5723056)
Code:

sudo find . -iname "*.jpg" -iname "*.jpeg" -iname "*.png" -iname "*.gif" -iname "*.bmp" -iname "*.tiff"

You need to put "-or" between each off your filename conditions. Otherwise it looks for files that fulfill all these conditions, e.g. files that end with .jpg and .jpeg and so forth which is a contradiction.

As next step, try the -exec part in rtmistler answer. The syntax of find is akward here but it will work. Alternatively you may pass finds output to the cp cmd as follows.

Code:

find . -iname "*.jpg" -or -iname "*.jpeg"  | xargs cp -t /home/name/restore/pics/
Why and how this exactly works is another story.

BW-userx 06-15-2017 11:47 AM

Quote:

Originally Posted by Sideroxylon (Post 5723056)
Code:

sudo find . -iname "*.jpg" -iname "*.jpeg" -iname "*.png" -iname "*.gif" -iname "*.bmp" -iname "*.tiff"
I used this one but it gives no output.

try it like this
Code:

find . -type f \( -name "*.jpg" -o -name "*.png" -o -name "*.tiff" \) -exec cp {} /media/data/testPhotos \;
you got a be in the working dir to run it. or you can replace the dot . with an absolute (search) path or two or three or four just add them in series using spaces between paths.
Code:

find /usr/local /etc /usr/bin -type f -name "*.goBa"
that will cause it to traverse through all of the paths one at a time
if you need to add more file types just repeat the pattern. -o -name "*.gif" etc..

Sideroxylon 06-15-2017 11:49 AM

Quote:

Originally Posted by sweepnine (Post 5723071)
The find-cmd as suggested by rtmistler is nontheless best way for you though a bit steep.



You need to put "-or" between each off your filename conditions. Otherwise it looks for files that fulfill all these conditions, e.g. files that end with .jpg and .jpeg and so forth which is a contradiction.

As next step, try the -exec part in rtmistler answer. The syntax of find is akward here but it will work. Alternatively you may pass finds output to the cp cmd as follows.

Code:

find . -iname "*.jpg" -or -iname "*.jpeg"  | xargs cp -t /home/name/restore/pics/
Why and how this exactly works is another story.

I read it implies the "-and" if I don't specificy anything. I assumed a different meaning there. Also the man page says that -exec is highly "insecure" and one should use -execdir instead.

Sideroxylon 06-15-2017 12:46 PM

Code:

find . -type f \( -name "*.jpg" -o -name "*.png" -o -name "*.tiff" \)
Now this one definitely worked like a charm! Thanks for that.

BW-userx 06-15-2017 12:52 PM

Quote:

Originally Posted by Sideroxylon (Post 5723111)
Code:

find . -type f \( -name "*.jpg" -o -name "*.png" -o -name "*.tiff" \)
Now this one definitely worked like a charm! Thanks for that.

you're welcome


All times are GMT -5. The time now is 03:21 AM.