Is there a way to mv
,cp
, or any file operation such that I could specify all the files I don't want affected?
For example, say I have a folder with the files file1
, file2
, and file3
, and I want to move file1
and file2
somewhere. Rather than explicitly naming the files to move (mv file1 file2 /path/to/destination
), I want to name the files not to move and have all the others in the folder get moved (mv --some-switch file3 /path/to/destination
)
Best Answer
You can use the advanced globbing patterns in some shells to match all the files in a directory except for those matching a particular pattern. For example, in ksh, bash or zsh, the command
will move all files in
/source
to/destination
except for the files matching*.bak
. In zsh, you can also write/source/^*.bak
if you first runsetopt extended_glob
, and more generally (again requiringsetopt extended_glob
)/source/*~*.bak
(or/source/a*~*.bak
for all files whose name begins witha
except for.bak
files, etc).Zsh has a mass copy/move/link command that can be used, amongst others, to move all files except for those matching a pattern. For example, the following command moves all files except
*.bak
from/source
totarget
, and adds.bak
to their name in the process:There are several commands called
rename
floating around. On Debian and Ubuntu,/usr/bin/rename
is a perl script that moves files to a new name generated by a perl expression. You can exclude files from renaming by not generating a new name if the file is to be excluded. For example, the following command (using this particularrename
program) moves all files except*.bak
from/source
to/target
:You can use the
find
command to select the files you want to move. For example, the following command moves all regular files except*.bak
in/source
or a subdirectory into/target
(note that the directory structure is collapsed):or (more efficient if there are many files to move)
rsync
is a generalization ofcp
andscp
with very powerful include/exclude rules. For example, the following command copies all files except*.bak
in/source
or a subdirectory into/target
, respecting the directory structure:pax
is (amongst other things) anothercp
on steroids. Its exclusion rules are not nearly as powerful as rsync's, but it has the additional ability to rename files as they are copied. If you rename a file to the empty string, it's excluded from the copy. For example, the following command copies all files except*.bak
in/source
or a subdirectory into/target
, and renames the files to.bak
in passing.The example above has the unfortunate side effect of creating directories called
foo.bak
, which can be avoided by combiningfind
withpax
: