LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Help with "cp" command syntax (https://www.linuxquestions.org/questions/linux-newbie-8/help-with-cp-command-syntax-500147/)

jstars 11-09-2006 03:37 PM

Help with "cp" command syntax
 
I have a directory with many sub-directories, each containing flies. I would like to copy all of these files (but not the directories) to another directory.

My attempts at recursively doing this with "-R" as well as "! -type d" does not work.

zhangmaike 11-09-2006 04:05 PM

Ok... let me see if I understand what you're trying to do...

You want to copy the non-directory contents of a tree of directories... for example, given the following tree:
./a/b/file1
./a/file2
./a/b/c/file3

you want file1, file2, and file3 to be copied elsewhere without maintaining the directory structure.

You CANNOT do this with a single cp command - copying files recursively without maintaining the directory structure doesn't really make sense. Still, it's not an impossible or difficult task - you could do it in one line with find.

Code:

find DIRECTORY_TO_COPY -not -type d -exec cp -d -i "{}" DESTINATION_DIRECTORY \;
Obviously, by removing the directory structure, some files may have the same name. Using the -i flag for cp (as above) will have cp warn you if this happens. The -d flag will have cp preserve symbolic links.

See man cp.

See man find.

pixellany 11-09-2006 04:13 PM

Quote:

Originally Posted by jstars
I have a directory with many sub-directories, each containing flies. I would like to copy all of these files (but not the directories) to another directory.

My attempts at recursively doing this with "-R" as well as "! -type d" does not work.

For reasons already noted---and probably some others--I think it will be far better to copy the whole structure--sub-directories and all. For most things, the extra sub-directories can't really hurt antyhing, and you can always do more "clean-up" later.

matthewg42 11-09-2006 05:14 PM

If you really want to copy the files from all sub-directories to a ginle directory, try this:
Code:

find /path/to/src/dir -type f -exec cp -i "{}" /path/to/dest/dir \;
The -i option to the cp command will make it interactively ask before over-writing files with duplicate names. Clearly this is not suitable for operation inside a non-interactive script, but it should give you some safety in case there are files with the same name within your hierarchy of source directories..

jstars 11-09-2006 06:02 PM

Thanks, I'll give it a try. Admittedly I didn't think about the dangers of filenames with the same name.

A poster above opined that it didn't really make sense to do this operation. There is a practical reason why I'm doing it: The sub-directories contain images. For presentation purposes I want to place all images in one directory so that they can be viewed sequentially would having to navigate between directories.

syg00 11-09-2006 06:24 PM

In which case you might find "mv" a better option.
Or mmv even better if you have it on your distro.

Multiple copied of images can eat disk space real quick.

matthewg42 11-09-2006 06:31 PM

Quote:

Originally Posted by jstars
For presentation purposes I want to place all images in one directory so that they can be viewed sequentially would having to navigate between directories.

Another approach for doing this would be to leave the original files where they are, and create a directory full of symlinks to them. I've done this myself actually :)

You can generate the filename with a sequentially numbered prefix so it doesn't matter if there are duplicate names:

Code:

$ mkdir picture_links
$ cd picture_links
$ n=1
$ find /my/src/directory -type f | while read f; do ln -s "$f" "${n}_${f##*/}"; let n+=1; done

The most cryptic bit here is the ${n}_${f##*/}. The ${f##*/} is a way to get the file name without the directory name. This is sometimes referred to as the basename of the path. There is a program which ships with most Linux systems to do this, but this method is an internal shell feature which is much quicker to call than invoking a separate program for each file processed. See the "Parameter Expansion" section of the bash manual page for more details.

The expansion of the n variable uses the braces because id we wrote this:
Code:

$n_${f##*/}
...the shell would try to expand the variable named n_ (which would expand to an empty string since this is probably not defined).


All times are GMT -5. The time now is 06:28 AM.