cp command to exclude certain files from being copied
Solution 1
Use rsync
:
rsync -av --exclude='path1/to/exclude' --exclude='path2/to/exclude' source destination
Note that using source
and source/
are different. A trailing slash means to copy the contents of the folder source
into destination
. Without the trailing slash, it means copy the folder source into destination
.
Alternatively, if you have lots of directories (or files) to exclude, you can use --exclude-from=FILE
, where FILE
is the name of a file containing files or directories to exclude.
-av
means archive mode and verbose.
--exclude
may also contain wildcards, such as --exclude=*/.svn*
.
Copied From: https://stackoverflow.com/a/2194500/749232
If you want to use cp
itself:
find . -type f -not -iname '*/not-from-here/*' -exec cp '{}' '/dest/{}' ';'
This assumes the target directory structure is the same as the source's.
Copied From: https://stackoverflow.com/a/4586025/749232
Solution 2
Late into the game but here is a very different solution using plain Bash and cp
: you can use a global file specification while having some files ignored.
Assume the directory contains the files:
$ ls *
listed1 listed2 listed3 listed4 unlisted1 unlisted2 unlisted3
Using the GLOBIGNORE variable:
$ export GLOBIGNORE='unlisted*'
$ ls *
listed1 listed2 listed3 listed4
Or with more specific exclusions:
$ export GLOBIGNORE='unlisted1:unlisted2'
$ ls *
listed1 listed2 listed3 listed4 unlisted3
Or using negative matches:
$ ls !(unlisted*)
listed1 listed2 listed3 listed4
This also supports several unmatched patterns:
$ ls !(unlisted1|unlisted2)
listed1 listed2 listed3 listed4 unlisted3
Solution 3
Quick Start
Run:
rsync -av --exclude='path1/in/source' --exclude='path2/in/source' [source]/ [destination]
Notes
-
-avr
will create a new directory named[destination]
. -
source
andsource/
create different results:-
source
— copy the contents of source into destination. -
source/
— copy the folder source into destination.
-
- To exclude many files:
-
--exclude-from=FILE
—FILE
is the name of a file containing other files or directories to exclude.
-
-
--exclude
may also contain wildcards:- e.g.
--exclude=*/.svn*
- e.g.
Modified from: https://stackoverflow.com/a/2194500/749232
Example
Starting folder structure:
.
├── destination
└── source
├── fileToCopy.rtf
└── fileToExclude.rtf
Run:
rsync -av --exclude='fileToCopy.rtf' source/ destination
Ending folder structure:
.
├── destination
│ └── fileToExclude.rtf
└── source
├── fileToCopy.rtf
└── fileToExclude.rtf
Solution 4
You can use cp
with the !
character.
For example, to exclude the file or files file.txt
, test.jpg
and the directory nodir
, while copying all others from the source
directory to the destination
directory, you may run:
cp source/!(file.txt|test.jpg|nodir) destination
If you have, for example, a file structure as this one:
.
├── destination
└── source
├── file.rtf
├── file.txt
├── test.jpg
├── yes
| └── test.jpg
└── nodir
└── other.jpg
The result after running the above command is:
.
└── source (not modified)
└── destination
├── file.rtf
└── yes
└── test.jpg
Here is an article with information on rsync
and cp
with exclude: How to cp copy and exclude internal files or directories (equivalent to rsync –exclude)
Related videos on Youtube
Stephen Jacob
A Civil and Structural Engineer with background in application of High Performance Computing in evacuation from Tsunami with cities damaged by earthquake. Currently, trying to hone my skills in Civil and Structural engineering, and Machine learning using Python.
Updated on September 18, 2022Comments
-
Stephen Jacob almost 2 years
Is there a way to use the
cp
command to copy a directory and exclude certain files/sub-directories within it? -
Rockallite over 4 yearsBTW, to turn off extended glob, run
shopt -u extglob
. -
AveryFreeman almost 4 yearsI generally use -avh --progress as a rule, add --ignore-existing if copying to a destination that gets regular backups and want to skip files that match created/modified time and size, and add --delete-after if deleted files in source and destination should reflect those deletions. -z is compression and can help make the transfer a little faster if backing up to a remote location (fairly unnecessary on LAN). --bwlimit=10000 (rate given in KB/s) will limit speed to 10MB/s and is helpful for long backup if concerned about hampering total bandwidth.
-
Mohammed Joraid over 3 yearsThe word "contents" in "copy the contents of the folder..." is a major keyword to understand the sentence. It should be bolded and highlighted.
-
Cadot.eu over 2 yearsif you use this script in bash file, add #!/bin/bash shopt -s extglob for remove error on (
-
Cadot.eu over 2 yearsthanks @BeastOfCaerbannog
-
BeastOfCaerbannog over 2 yearsYou're welcome! :)