I would like to copy all files out of a dir except for one named Default.png. It seems that there are a number of ways to do this. What seems the most effective to you?
-
Why do you need it to skip that file, as opposed to just deleting it after copying it? Does it exist in the target directory already? – Lasse V. Karlsen Aug 21 '09 at 18:48
-
1Yes a file with the same name is already living in the target dir. – Joe Cannatti Aug 21 '09 at 20:53
-
1@LasseV.Karlsen: Or you could want to save the time of copying it, if it's a large file. I'm interested in this but excluding a directory rather than a file. – Nikana Reklawyks Nov 20 '12 at 16:13
9 Answers
Should be as follows:
cp -r !(Default.png) /dest
If copying to a folder nested in the current folder (called example in the case below) you need to omit that directory also:
cp -r !(Default.png|example) /example

- 62,090
- 32
- 125
- 150
-
20
-
Are you copying the files to a folder nested within the folder your copying from? – Jonathan Holloway Aug 21 '09 at 18:48
-
55This requires `shopt -s extglob` to work, if it has been disabled. – Barry Kelly Aug 21 '09 at 18:52
-
5It seems that OS X needs to use `shopt -s extglob` as described by @BarryKelly. With that, it works perfectly. – Kat Jul 08 '14 at 23:45
-
1Years on Bash and didn't know about `!()`... Beautiful! For those that --like me-- feel it is time to study/review [bash](https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html), here are the relevant links related to this question/answer: [shopt/extglob](https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html) and [the pattern](https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html#Pattern-Matching). – Brandt Nov 26 '19 at 13:45
-
Just because I didn't quite grasp, at first, how to use this: `cp -r $src_path/!($file) $dest_path` would be equivalent to `cp $src_path/* $dest_path/ --exclude $file` if cp had such an argument. – mazunki Jul 11 '20 at 21:01
rsync has been my cp/scp replacement for a long time:
rsync -av from/ to/ --exclude=Default.png
-a, --archive archive mode; equals -rlptgoD (no -H,-A,-X)
-v, --verbose increase verbosity
-
-
multiple --exclude= arguments are supported. And don't forget the `-r` arg if you're syncing directories – Rian Sanderson Apr 27 '19 at 06:34
-
Note that it also copies hidden files (eg .git) and in case of same files overwrites them – Islam Murtazaev Nov 13 '20 at 10:35
-
this"rsync -aP --exclude=backup /root/jenkins_api/* /root/jenkins_api/backup" does not work when there is no files in /root/jenkins_api/**.Is there a workaround to skip when no files are found ? – Youssef Boudaya Jun 24 '21 at 15:27
Simple, if src/
only contains files:
find src/ ! -name Default.png -exec cp -t dest/ {} +
If src/
has sub-directories, this omits them, but does copy files inside of them:
find src/ -type f ! -name Default.png -exec cp -t dest/ {} +
If src/
has sub-directories, this does not recurse into them:
find src/ -type f -maxdepth 1 ! -name Default.png -exec cp -t dest/ {} +

- 349,597
- 67
- 533
- 578
-
5This turns out to be the best for me because it would appear that OS X ships without glob enabled. – Joe Cannatti Aug 21 '09 at 20:54
-
6@Max `\;` executes the command once per file. `+` runs the command once and passes all of the file names to it at once (subject to the command line length limit). `+` is a bit more efficient in general. – John Kugelman Sep 22 '14 at 00:48
cp `ls | grep -v Default.png` destdir

- 115,893
- 19
- 128
- 203
-
6This is more likely to produce errors than do what you intend. – Dennis Williamson Aug 22 '09 at 01:40
-
-
1@arthur.sw For one thing, it doesn't account for files with spaces in it. As with many things with the shell, there's a bunch of edge cases that fail. 95%+ of the time, this stuff just works. Just need to be conscious of the caveats. Spaces in file names jump working with the shell from trivial to painful. – Will Hartung Mar 02 '21 at 17:50
-
Another reason is that since there are no anchors in the regex and the dot isn't escaped it would also match a file named `myDefaultXpng.OLD` for example. – Dennis Williamson Jun 27 '22 at 13:11
I'd just do:
cp srcdir/* destdir/ ; rm destdir/Default.png
unless the files are big. Otherwise use e.g.
find srcdir -type f/ |grep -v Default.png$ |xargs -ILIST cp LIST destdir/
-
4The first command is not what the OP asked for. If `Default.png` exists in the two directories, it will replace the one in `destdir` by the one in `srcdir`, then delete the copied `Default.png`. Instead, the OP wants to keep the `Default.png` that already exists in `destdir`. – SnowFrog May 22 '17 at 11:34
-
3how about default.png already exists in destdir? Your solutioun won't work. – Iman Mohamadi Jun 03 '18 at 08:10
Jan, 2022 Update:
This is the easiest way(It's not complicated).
First, make "temp" folder:
mkdir temp
Second, copy all files from your original folder to "temp" folder:
"-R" flag can copy exactly all files including "Symbolic Links"
cp -R originalFolder/. temp/
Third, remove "Default.png" from "temp" folder:
rm temp/Default.png
Finally, copy all files from "temp" folder to your destination folder:
cp -R temp/. destinationFolder/
In addition, this is the shortest way without "temp" folder:
cp -R originalFolder/!(Default.png) destinationFolder/

- 22,221
- 10
- 124
- 129
Below script worked for me
cp -r `ls -A | grep -v 'skip folder/file name'` destination

- 1,928
- 1
- 13
- 15
# chattr +i /files_to_exclude
# cp source destination
# chattr -i /files_to_exclude

- 1
- 1
use the shell's expansion parameter with regex
cp /<path>/[^not_to_copy_file]* .
Everything will be copied except for the not_to_copy_file
-- if something is wrong with this. please Specify !

- 1
-
3Welcome to SO. Unfortunately your answer is not correct. The bracket expresssion (`[...]`) contains a set of characters to match, while a leading `^` will cause a match of the complement of the listed characters. In the following example, neither file will be listed: `touch not_to_copy_file to_copy_file ; ls [^not_to_copy_file]*` because all filenames starting with any of the following characters will be excluded: `_cefilnopty`. – rtx13 Apr 02 '20 at 04:56