How to exclude a folder when using the mv command
Solution 1
This doesn't have anything to do with mv
, but is a bash
feature, citing man bash
:
If the extglob shell option is enabled using the shopt builtin, several extended pattern matching operators are recognized. In the following description, a pattern-list is a list of one or more patterns separated by a |. Composite patterns may be formed using one or more of the following sub-patterns:
!(pattern-list)
Matches anything except one of the given patterns
!(f1)
matches f2 f3
in your example, so effectively you're doing:
mv -t f3/ f2 f3 f2
Then, it successfully moves f2
to f3
, raises the first error trying to move f3
to itself, and raises the second error when trying to move f2
to f3
again because it was already moved and is no longer in the current directory.
To achieve your goal you should rather do:
mv -t f3/ !(f[13]) # or !(f1|f3)
This expression matches everything except f1
and f3
.
This also works with *
, ?
and […]
:
$ ls
e1 e2 e3 f1 f2 f3
$ ls !(e*|?[12])
f3
Solution 2
!(f1)
is an extended glob expression, so (provided the extglob
shell option is set) it expands to a list of (non)-matching files. In other words, if your directory originally contained f1
, f2
, f3
then
mv -t f3/ !(f1) f2
expands as
mv -t f3/ f2 f3 f2
The first error should be obvious; the second is because it attempts to move f2
twice - and fails the second time.
Solution 3
If you're looking for a way to backup current files, it would be safer to split the move command into copy & remove. For example:
# Allow wildcard and hidden files search
shopt -s extglob dotglob
# Make a new directory (skip if exists)
mkdir -p BACKUP
# Copy all files to BACKUP (-a to keep attributes, -f to overwrite existing)
cp -af !(BACKUP) BACKUP/
# Remove all files except BACKUP (and hidden files starting with ".keep")
rm -rf !(BACKUP|.keep*)
Related videos on Youtube
![George Udosen](https://i.stack.imgur.com/l1Lwr.jpg?s=256&g=1)
George Udosen
Fullstack developer | Python | GCP, Azure Cloud Certified | AWS & Azure Cloud Savy | Linux Sysadmin | Bash script writer | Google IT Support Professional...
Updated on September 18, 2022Comments
-
George Udosen almost 2 years
I have this situation where I want to exclude a directory while using the
mv
command. I saw this example where the syntax would be!(exclude_dir)
, but when I set up a scenario to test it I get results that I don't fully understand.Now I have created three folders:
f1
,f2
andf3
. Now I use the command in this way:mv -t f3/ !(f1) f2
This produces this error:
mv: cannot move 'f3' to a subdirectory of itself, 'f3/f3' mv: cannot stat 'f2': No such file or directory
Now funny thing is the structure of the folder is now:
. ├── f1 └── f3 └── f2 3 directories, 0 files
It does what I want but why the error messages. Obviously I am not using that command correctly.