cp only files, skipping directories
I suggest you to use rsync instead of cp, if you can it has the option -m that will exclude empty folders, example:
rsync -am <origin> <destination>
Explanation of the command in explainshell.com
I'm using the -a option because it does a lot of nice default action, but if you want you can also use the -r option, that will set the recursive mode only.
[ADD comment]
I do not know of a way to do this with cp, at least the man page does not show any option that will do that for you.
You probably can do a more complex solution by using the command find
to find list of files/directories to copy, and then pass it to cp, but that would be much more complicated than rsync. rsync is even pretty much standard in many linuxes
cp
indeed doesn't have an option to get only files, but as berserck said, you can use find
together with cp
. In fact, this is really straightforward:
# Copy only files
find /path/to/file -type f -execdir cp "{}" /dest/path ";"
Or:
# Copy everything except directories
find /path/to/file -not -type d -execdir cp "{}" /dest/path ";"
Explanation
find
is the tool that will look for the files you want. In the first option, we set -type f
to return only regular files. In the second option, we set the -not -type d
to get everything except directories. find
executes the arguments passed to -execdir
replacing {}
with one result entry at a time and stops the command when ;
is found (;
should to be escaped \;
or ";"
, or the shell might expand it).
-execdir
will run the command having the file's folder as its "working directory" and it is preferable instead of -exec
, check below.
The -type
option documentation:
-type c
File is of type c:
b: block (buffered) special
c: character (unbuffered) special
d: directory
p: named pipe (FIFO)
f: regular file
l: symbolic link; this is never true if the -L option or the -follow option is in effect, unless the symbolic link is broken. If you want to search for symbolic links when -L is in effect, use -xtype.
s: socket
D: door (Solaris)
The -not
option documentation:
! expr
True if expr is false. This character will also usually need protection from interpretation by the shell.
-not expr
Same as ! expr, but not POSIX compliant.
The -execdir
option documentation:
-exec command ;
Execute command; true if 0 status is returned. All following arguments to find are taken to be arguments to the command until an argument consisting of ';' is encountered. The string '{}' is replaced by the current file name being processed everywhere it occurs in the arguments to the command [...]. Both of these constructions might need to be escaped (with a '\') or quoted to protect them from expansion by the shell. The specified command is run once for each matched file. The command is executed in the starting directory. There are unavoidable security problems surrounding use of the -exec action; you should use the -execdir option instead.
-execdir command ;
Like -exec, but the specified command is run from the subdirectory containing the matched file, which is not normally the directory in which you started find. This a much more secure method for invoking commands, as it avoids race conditions during resolution of the paths to the matched files. [...] If you use this option, you must ensure that your $PATH environment variable does not reference '.'; otherwise, an attacker can run any commands they like by leaving an appropriately-named file in a directory in which you will run -execdir. The same applies to having entries in $PATH which are empty or which are not absolute directory names.
https://linux.die.net/man/1/find