Reputation: 133
So I've been working on a script for the past few days and have come across this horrible issue! I am trying to delete all the contents of a folder except for one single file. I've enabled the "extglob" shell option already in the bash script with shopt -s extglob
and I've setup my commands correctly to my knowledge. Here's an example of my issue:
#!/bin/bash
drive=$1
outpath=/media/removable/$drive/test
shopt -s extglob
if [[ $2 = "Delete" ]];then
rm -rvf $outpath/* !($outpath/save.tar)
# Also tried this:
# rm -rvf !($outpath/save.tar) $outpath/*
exit
fi
(Not my actual file but an example.)
My directory was set to /
and for some reason it started deleting every single file in my root directory that it had permission to damage. I don't particularly care about recovering from this, my script is simply not working and I can't get it to exclude this one file. I've tried the example above, I've tried rm -rvf $outpath/* $outpath/!(save.tar)
and nothing seems to work. Does anyone know how to properly use the ~("path/to/file") to exclude a file/path? Particularly while using variables to define the path?
Upvotes: 1
Views: 57
Reputation: 85683
Assuming save.tar
is inside the test
folder, you don't need to use a separate path to exclude the file from getting deleted. The negate operator already globs all the files except the one you provide inside !()
.
You can just do
rm -rvf "$outpath"/!(save.tar)
Or if you multiple .tar
files which need to be excluded, you can move the glob inside the negation as !(*.tar)
which means delete everything except the files ending with .tar
A simple reproducible example of your problem is below. Here all the files except file6
are commanded to be deleted and works as expected.
$ mkdir -p /tmp/foo/bar/test
$ touch /tmp/foo/bar/test/file{1..7}
ls /tmp/foo/bar/test/
file1 file2 file3 file4 file5 file6 file7
$ outpath=/tmp/foo/bar/test
$ rm -rvf "$outpath"/!(file6)
removed ‘/tmp/foo/bar/test/file1’
removed ‘/tmp/foo/bar/test/file2’
removed ‘/tmp/foo/bar/test/file3’
removed ‘/tmp/foo/bar/test/file4’
removed ‘/tmp/foo/bar/test/file5’
removed ‘/tmp/foo/bar/test/file7’
See more on bash extended globbing.
Upvotes: 2