How to copy (or cp) files recursively with exclusions in Linux system
Problem
How to copy or cp
files from a source to a destination recursively with some exclusions in a Linux operating system?
For example, I have a directory named A
as follows:
➜ tree AA├── DEPENDENCIES├── a.log├── b.log├── c.log└── maven └── org.apache.httpcomponents └── httpclient ├── pom.properties └── pom.xml3 directories, 6 files
Now, I want to copy directory A
to directory B
recursively, but I don’t want to copy the log files to B
.
Environment
- Linux or MacOS
Solution
We can use rsync
to resolve this problem:
rsync -avr --exclude='*.log' A/* B
After running the above command, let’s check the destination directory B
:
B├── DEPENDENCIES└── maven └── org.apache.httpcomponents └── httpclient ├── pom.properties └── pom.xml
3 directories, 3 files
It works!
How it works?
The rsync
command can not only sync with a remote host’s directory but also sync with a local directory.
Let’s check the three options used in the above command:
-v, --verbose increase verbosity
-a, --archive archive mode; equals -rlptgoD (no -H,-A,-X) This is equivalent to -rlptgoD. It is a quick way of saying you want recursion and want to preserve almost everything (with -H being a notable omission).
-r, --recursive recurse into directories
The --exclude
option can be used with patterns:
--exclude=PATTERN
This option is a simplified form of the --filter option that defaults to an exclude rule and does not allow the full rule-parsing syntax of normal filter rules.
Aside from --exclude
, you can also use --exclude-from
, --include
, and --include-from
:
--exclude-from=FILEThis option is related to the --exclude option, but it specifies a FILE that contains exclude patterns (one per line). Blank lines in the file and lines starting with ';' or '#' are ignored. If FILE is -, the list will be read from standard input.
--include=PATTERNThis option is a simplified form of the --filter option that defaults to an include rule and does not allow the full rule-parsing syntax of normal filter rules.See the FILTER RULES section for detailed information on this option.
--include-from=FILEThis option is related to the --include option, but it specifies a FILE that contains include patterns (one per line). Blank lines in the file and lines starting with ';' or '#' are ignored. If FILE is -, the list will be read from standard input.
For example, if you want to exclude some types of files, just create a file named exclude.list
:
Content of exclude.list
:
ab.*tmp/g
Then run this command:
rsync -av --exclude-from=exclude.list /home/mysql/backup /home/mysql/backup2/
Summary
In this post, we explored how to use the rsync
command to copy files recursively while excluding specific file types or patterns. The --exclude
option is particularly useful for filtering out unwanted files during the copy process. Additionally, we discussed other related options like --exclude-from
, --include
, and --include-from
for more advanced use cases. This method is efficient and works seamlessly on both Linux and MacOS systems.
Final Words + More Resources
My intention with this article was to help others who might be considering solving such a problem. So I hope that’s been the case here. If you still have any questions, don’t hesitate to ask me by email: Email me
Here are also the most important links from this article along with some further resources that will help you in this scope:
Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!